两个头文件和两个cpp文件中的前向声明

时间:2017-01-23 21:46:11

标签: c++ cyclic-reference file-inclusion

我有四个C ++文件,两个标题和两个cpp。标题被正确保护,在第一个我使用这样的前向声明:

//A.h
class B;

class A {
public:
    A();
    void doSomething(B* b);
};

和一些实施:

void A::doSomething(B* b){
    b->add();
}

另一个标题如下:

#include "A.h"
class B {
public:
    B();
    void add();
};

void B::add(){
    cout << "B is adding" << endl;
}

我让&#34;会员访问不完整的B&#34;错误,我被困在那里。我需要在A中使用一个B,每个B必须有一个指向其所有者&#34;的指针,这是A的一个实例。我能做些什么来解决这种情况。

提前致谢

3 个答案:

答案 0 :(得分:0)

B.cpp文件尽管命名相似,但并未隐式包含B.h。您必须包含两个实现中的B.h。此外,如果您想包含 A.h B.h,请创建包含警卫

答案 1 :(得分:0)

通过在A和B类定义(标题)中使用前向声明来解决问题,包括B.cpp中的A.h以及A.cpp中的B.h.这是代码:

//A.h

#ifndef A_H_
#define A_H_

#include <iostream>

using namespace std;

class B;

class A{
public:
    A();
    virtual ~A();

private:
    B* pToB;

public:
    void doSomething(B* b);
    void SetB(B* b);
};

#endif

A类的cpp,请注意包含B.h(我通常不会这样做)

// A.cpp

#include "A.h"
#include "B.h"

A::A():pToB(){
    cout << "A constructor" << endl;
}

A::~A(){}

void A::SetB(B* b){
    this->pToB = b;
    cout << "setting B" << endl;
}

void A::doSomething(B* b){
cout << "A is gonna call B's method add: ";
    b->add();
}

现在是B班:

// B.h

#ifndef B_H_
#define B_H_

#include <iostream>

using namespace std;

class A;

class B{
public:
    B();
    virtual ~B();

private:
    A* pToA;

public:
    void add();
    void SetA(A* a);
};

#endif

实施B

// B.cpp

#include "B.h"
#include "A.h"

B::B():pToA(){
    cout << "B constructor” << endl;
}

B::~B(){}

void B::SetA(A* a){
    this->pToA = a;
    cout << "setting A" << endl;
}

void B::add(){
    cout << "B is adding" << endl;
}

cpp包括main函数(包括两个头文件,不包括在内)

#include "A.h"
#include "A.h"

int main() {
    A* newA = new A;
    B* newB = new B;
    newA->SetB(newB);
    newB->SetA(newA);
    newA->doSomething(newB);
    return 0;
}

此程序的输出如下:

A constructor
B constructor
setting B
setting A
A is gonna call B's method add: B is adding

感谢Sandeep Datta solution帮我解决了这个问题

答案 2 :(得分:-1)

在使用doSomething(B* b)方法之前,您需要拥有B类的定义,所以我想而不是:

class B;

class A {
public:
    A();
    void doSomething(B* b);
};

你需要做类似的事情:

class B;

class A {
public:
    A();
};

void A::doSomething(B* b);

之后声明它,因此编译器具有关于类B(内存分配等)所需的信息。