2

我有四个 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;
}

我收到“成员访问不完整的 B 型”错误,我被困在那里。我需要在 A 中使用 B 中的一个,并且每个 B 都必须有一个指向其“所有者”的指针,即 A 的一个实例。我能做些什么来解决这种情况。

提前致谢

4

3 回答 3

0

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

//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,注意包含 Bh(我通常不会这样做)

// 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(包括两个标题,不包括)

#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,他的解决方案帮助我解决了这个问题

于 2017-01-24T17:52:42.087 回答
0

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

于 2017-01-23T21:53:23.793 回答
-1

您需要先定义 B 类,然后才能使用该doSomething(B* b)方法,所以我认为不是:

class B;

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

您需要执行以下操作:

class B;

class A {
public:
    A();
};

void A::doSomething(B* b);

之后声明它,以便编译器获得它需要的关于 B 类的信息(内存分配等)。

于 2017-01-24T03:06:33.673 回答