#include <iostream>
using namespace std;
class A
{
private:
B b;
public:
void doSomething();
};
void A::doSomething()
{ b.doSomething(); }
class B
{
public:
void doSomething();
};
void B::doSomething()
{ cout<<"OK"<<endl; }
int main(int argc, char *argv[])
{
A * a = new A;
a->doSomething();
return 0;
}
首先让我们来看一下上面的这个程序代码,如果你直接执行它,会发现它有两个ERROR:
error: 'B' does not name a type
B b;
error: 'b' was not declared in this scope
{ b.doSomething(); }
很明显,在class A里引用的B b并没有声明,那么我们就在前面加一个前置声明class B:
#include <iostream>
using namespace std;
class B;
class A
{
private:
B b;
public:
void doSomething();
};
void A::doSomething()
{ b.doSomething(); }
class B
{
public:
void doSomething();
};
void B::doSomething()
{ cout<<"OK"<<endl; }
int main(int argc, char *argv[])
{
A * a = new A;
a->doSomething();
return 0;
}
但这样执行,还是会出现ERROR:
error: field b has incomplete type
B b;
嗯?这是什么情况?赶紧去网上搜一搜——
程序编译出现"field has incomplete type"问题的解决
“类或结构体的前向声明只能用来定义指针对象或引用,因为编译到这里时还没有发现定义,不知道该类或者结构的内部成员,没有办法具体的构造一个对象,所以会报错。
将类成员改成指针就好了。”
那是不是说,把B b改成B *b就行了呢?
Sorry,你就算改了,还是会有ERROR:
error: request for member 'doSomething' in '((A*)this)->A::b', which is of pointer type 'B*' (maybe you meant to use '->' ?)
{ b.doSomething();}
这是一种治标不治本的方法,那么有没有治本的方法呢?嗯,我们确实有一个更加简单的方法。
既然说了在编译到B b时没有发现定义就会报错,那么我们把class B的定义改到前面来不久行了吗?
#include <iostream>
using namespace std;
class B;
class B
{
public:
void doSomething();
};
void B::doSomething()
{ cout<<"OK"<<endl; }
class A
{
private:
B b;
public:
void doSomething();
};
void A::doSomething()
{ b.doSomething(); }
int main(int argc, char *argv[])
{
A * a = new A;
a->doSomething();
return 0;
}
运行一下——
嗯,结束了。