问题引出
C++中两个类互相包含是无法通过编译的:
1 2 3 4 5 6 7 |
class B; class A{ B b; } class B{ A a; } |
编译报错:
1 2 3 4 5 |
main.cpp:7:4: error: field 『b』 has incomplete type 『B』 B b; ^ main.cpp:5:7: note: forward declaration of 『class B』 class B; |
原因很简单,创建 A 时要先创建 B,然后创建 B 又要创建 A,反反复复就会进入死循环,编译肯定报错。
解决方案一:使用指针
当两个类要互相包含时,要求其中一个类必须使用指针的形式,并且包含类中对于被包含类的调用不能早于被包含类的定义之前。
第一句话好理解,把代码改成以下形式即可:
1 2 3 4 5 6 7 |
class B; // B 的声明不能省略 class A{ B *b; }; class B{ A a; }; |
对于第二句话包含类中对于被包含类的调用不能早于被包含类的定义之前的理解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class B; class A{ void showB();/*{ // B.value 的声明位于该语句之后,不能调用 cout << b->value << endl; }*/ B *b; }; // 调用失败,因为 b->value 此时并没有声明 void A::showB(){ cout << b->value << endl; } class B{ public: B(){ value=1; } A a; int value; }; |
编译出错:
1 2 3 4 5 6 7 8 9 10 11 |
main.cpp:14:11: error: invalid use of incomplete type 『class B』 cout << b->value << endl; ^~ main.cpp:5:7: note: forward declaration of 『class B』 class B; ^ main.cpp:14:13: error: invalid use of incomplete type 『class B』 cout << b->value << endl; ^~~~~ main.cpp:5:7: note: forward declaration of 『class B』 class B; |
需要把 A::showB() 的定义移到类 B 的声明之后:
1 2 3 4 5 6 7 8 9 10 11 12 |
class B{ public: B(){ value=1; } A a; int value; }; void A::showB(){ cout << b->value << endl; } |
解决方案二:不实例对象 B
如果在对象 A 中仅仅只是使用对象 B 作为成员函数的形参,则可以不用使用指针。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class B; class A{ void showB(B b); }; class B{ public: B(){ value=1; } A a; int value; }; void A::showB(B b){ cout << b.value << endl; } |
同样,也和上面一样,A 中使用 B 也要在 B 的声明之后,把 A::showB()
放到 class B
之前编译也会不通过。
评论