由一次ERROR想到的

#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;
}

运行一下——


嗯,结束了。

猜你喜欢

转载自blog.csdn.net/qq_41563660/article/details/80782894