Chinaunix首页 | 论坛 | 博客
  • 博客访问: 42844
  • 博文数量: 13
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 145
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-19 10:39
文章分类

全部博文(13)

文章存档

2016年(3)

2015年(5)

2014年(5)

我的朋友

分类: C/C++

2015-09-10 00:48:27

当A对象的头文件中,有用到B对象,
而且B对象的头文件中,也有用到A对象,这2者同时满足时。
我们就要用到 头部类申明  class XXX;

e.g.  父子关系
<父>---------------------------------------------------------------------------

点击(此处)折叠或打开

  1. //
  2. // father.h
  3. //

  4. #ifndef FATHER_H
  5. #define FATHER_H

  6. //
  7. // Previous Declaration
  8. //
  9. class Son;

  10. class Father
  11. {
  12. public:
  13.     Father(int age);
  14.     void pt();
  15.     void setSon(Son* s);
  16.     void ptSon();
  17. private:
  18.     int m_age;
  19.     Son* m_Son;
  20. };

  21. #endif

点击(此处)折叠或打开

  1. //
  2. // father.cpp
  3. //

  4. #include <iostream>

  5. #include "father.h"
  6. #include "son.h"

  7. using namespace std;

  8. Father::Father(int age)
  9.     : m_age(age)
  10.     , m_Son(nullptr)
  11. {
  12. }


  13. void Father::pt()
  14. {
  15.     cout << "I'm Father , I'm " << m_age << " years old. " << endl;
  16. }


  17. void Father::setSon(Son* s)
  18. {
  19.     m_Son = s;
  20. }

  21. void Father::ptSon()
  22. {
  23.     if( m_Son!=nullptr ) {
  24.         m_Son->pt();
  25.     }
  26. }

<子>---------------------------------------------------------------------------

点击(此处)折叠或打开

  1. //
  2. // son.h
  3. //

  4. #ifndef SON_H
  5. #define SON_H


  6. #include "father.h"

  7. class Son
  8. {
  9. public:
  10.     Son(Father* pFa,int age);
  11.     void pt();
  12.     void ptFather();
  13. private:
  14.     Father* m_pFather;
  15.     int m_sonAge;
  16. };

  17. #endif

点击(此处)折叠或打开

  1. //
  2. // son.cpp
  3. //

  4. #include <iostream>

  5. // #include "father.h"
  6. #include "son.h"

  7. using namespace std;


  8. Son::Son(Father* pFa, int age)
  9.     : m_pFather(pFa)
  10.     , m_sonAge(age)
  11. {
  12. }


  13. void Son::pt()
  14. {
  15.     cout << "I'm Son , I'm " << m_sonAge << " years old. " << endl;
  16. }


  17. void Son::ptFather()
  18. {
  19.     if( m_pFather!=nullptr ) {
  20.         m_pFather->pt();
  21.     }
  22. }
这里注意 , son.h , son.cpp 有2种写法
1.  如上面的代码
2.  注释掉 son.h                  第9行     #include "father.h"
   
然后取消注释  son.cpp    第7行   #include "father.h"
   !!!!!  请注意   son.cpp 中  #include "father.h" 一定要放在 #include "son.h" 之前  !!!!!
   因为 在展开 son.h头文件后,会因为找不到 father类的定义,而编译失败
   如果硬要把 #inlclude "father.h" 放在 #include "son.h" 之后,那么,就必须在 #include "son.h" 之前加前置类申明   , 添加此语句     class Father;


点击(此处)折叠或打开

  1. //
  2. // main.cpp
  3. //

  4. #include <iostream>
  5. using namespace std;

  6. #include "father.h"
  7. #include "son.h"

  8. int main(int argc, char* argv[])
  9. {
  10.     Father* pFa = new Father(50);
  11.     Son* pSon = new Son(pFa,20);
  12.     pFa->setSon(pSon);

  13.     pFa->pt();
  14.     pFa->ptSon();

  15.     cout << "---------------------------------------------" << endl;
  16.     
  17.     pSon->pt();
  18.     pSon->ptFather();

  19.     //
  20.     // delete object
  21.     //
  22.     delete pFa;
  23.     pFa = nullptr;
  24.     delete pSon;
  25.     pSon = nullptr;

  26.     return 0;
  27. }

附上 makefile

点击(此处)折叠或打开

  1. # makefile
  2. all:main.o father.o son.o
  3. g++ --std=c++11 -g3 -Wall main.o father.o son.o -o main
  4. main.o:main.cpp father.h son.h
  5. g++ --std=c++11 -g3 -Wall -o main.o -c main.cpp
  6. father.o:father.h father.cpp
  7. g++ --std=c++11 -g3 -Wall -o father.o -c father.cpp
  8. son.o:son.h son.cpp
  9. g++ --std=c++11 -g3 -Wall -o son.o -c son.cpp
  10. .PHONY:clean
  11. clean:
  12. -rm -fR main.dSYM main.o father.o son.o main




------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------


<复杂情况>
在相互包含的类外面有  命名空间  时,  代码就难写很多,试了多次,都编译失败
编译错误写法枚举:  (均在 father.h 头文件中修改的 )
1. 在 class Son; 行处修改成  -->   class S::Son;
2. 在 class Son;行处之上添加 using namespace S一行;
3. 注释掉 class Son;行  ,  在 namespace Fa { 后面一行添加  class Son;1行
4. 注释掉 class Son;行  ,  在 namespace Fa { 后面一行添加  class S::Son;1行
5. 注释掉 class Son;行  ,  在 namespace Fa { 后面一行添加  using namespace S; class Son;2行
6. 注释掉 class Son;行  ,  在 namespace Fa { 后面一行添加  using namespace S;1行
7. 维护原来的写法

最终才知道,没有 class S::Son;  这种写法, class 后面直接,也只能接一个类名,不能在前面加命名空间
namespace S
{
    class Son;
}

才是正确的写法


点击(此处)折叠或打开

  1. //
  2. // father.h
  3. //

  4. #ifndef FATHER_H
  5. #define FATHER_H

  6. //
  7. // Previous Declaration
  8. //
  9. namespace S
  10. {
  11.     class Son;
  12. }


  13. namespace Fa
  14. {

  15. class Father
  16. {
  17. public:
  18.     Father(int age);
  19.     void pt();
  20.     void setSon(S::Son* s);
  21.     void ptSon();
  22. private:
  23.     int m_age;
  24.     S::Son* m_Son;
  25. };

  26. } // end namespace Father

  27. #endif


点击(此处)折叠或打开

  1. //
  2. // father.cpp
  3. //

  4. #include <iostream>

  5. #include "father.h"
  6. #include "son.h"

  7. using namespace std;

  8. namespace Fa
  9. {

  10. Father::Father(int age)
  11.     : m_age(age)
  12.     , m_Son(nullptr)
  13. {
  14. }


  15. void Father::pt()
  16. {
  17.     cout << "I'm Father , I'm " << m_age << " years old. " << endl;
  18. }


  19. void Father::setSon(S::Son* s)
  20. {
  21.     m_Son = s;
  22. }

  23. void Father::ptSon()
  24. {
  25.     if( m_Son!=nullptr ) {
  26.         m_Son->pt();
  27.     }
  28. }


  29. } // end namespace Father


点击(此处)折叠或打开

  1. //
  2. // son.h
  3. //

  4. #ifndef SON_H
  5. #define SON_H


  6. #include "father.h"

  7. namespace S
  8. {

  9. class Son
  10. {
  11. public:
  12.     Son(Fa::Father* pFa,int age);
  13.     void pt();
  14.     void ptFather();
  15. private:
  16.     Fa::Father* m_pFather;
  17.     int m_sonAge;
  18. };

  19. }    // end namespace S

  20. #endif


点击(此处)折叠或打开

  1. //
  2. // son.cpp
  3. //

  4. #include <iostream>


  5. // #include "father.h"
  6. #include "son.h"


  7. using namespace std;

  8. namespace S
  9. {

  10. Son::Son(Fa::Father* pFa, int age)
  11.     : m_pFather(pFa)
  12.     , m_sonAge(age)
  13. {
  14. }


  15. void Son::pt()
  16. {
  17.     cout << "I'm Son , I'm " << m_sonAge << " years old. " << endl;
  18. }


  19. void Son::ptFather()
  20. {
  21.     if( m_pFather!=nullptr ) {
  22.         m_pFather->pt();
  23.     }
  24. }

  25. } // end namespace S

点击(此处)折叠或打开

  1. //
  2. // main.cpp
  3. //

  4. #include <iostream>
  5. using namespace std;

  6. #include "father.h"
  7. #include "son.h"


  8. int main(int argc, char* argv[])
  9. {
  10.     Fa::Father* pFa = new Fa::Father(50);
  11.     S::Son* pSon = new S::Son(pFa,20);
  12.     pFa->setSon(pSon);

  13.     pFa->pt();
  14.     pFa->ptSon();

  15.     cout << "---------------------------------------------" << endl;
  16.     
  17.     pSon->pt();
  18.     pSon->ptFather();

  19.     //
  20.     // delete object
  21.     //
  22.     delete pFa;
  23.     pFa = nullptr;
  24.     delete pSon;
  25.     pSon = nullptr;

  26.     return 0;
  27. }




阅读(2026) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~