IT虾米网

c++之解决交叉引用

unruledboy 2023年09月15日 编程语言 33 0

我在创建具有不同对象类型的某种形式的层次结构时遇到问题。我有一个类(class),其中有另一个类(class)的成员,像这样:

class A 
{ 
public: 
    A(){} 
    ~A(){} 
 
    void addB(B* dep){ 
        child = dep; 
        dep->addOwner(this); 
    } 
    void updateChild(){ 
        child->printOwner(); 
    } 
    void print(){ 
        printf("Printing..."); 
    } 
private: 
    B* child; 
}; 

这是 B 类:

class B 
{ 
public: 
    void addOwner(A* owner){ 
        ownerObject = owner; 
    } 
 
    //ISNT WORKING 
    void printOwner(){ 
        ownerObject->print(); 
    } 
 
private: 
    A* ownerObject; 
}; 

从类“A”中调用“B”的函数工作得很好,但反之亦然会产生编译器错误,因为 A 未在 B 中定义。它实际上是通过使用包含和前向声明,但我猜测是编译器无法解决的交叉引用问题。

是否有机会解决这个问题,或者我应该重新考虑我的设计?

请您参考如下方法:

您说您已经通过使用 A 的前向声明而不是包含定义了 A 的 header 来解决循环依赖问题,因此您已经知道如何避免循环包含。但是,您应该注意 what is possible and what is not with incomplete types (即已向前声明的类型)。

在您的例子中,您尝试在类型不完整的对象上调用成员函数 print;编译器对这个类型一无所知,除了它会在某个时候被定义,所以它不允许你这样做。解决办法是把B头中printOwner成员函数的实现去掉,放到一个实现文件中:

//B.hpp 
 
class A; // forward declaration 
 
class B 
{ 
  public: 
    void addOwner(A* owner); 
 
    void printOwner() const; // I think this member function could be const 
 
  private: 
    A* ownerObject; 
}; 
 
//B.cpp 
 
#include "B.hpp" 
#include "A.hpp" // here we "import" the definition of A 
 
void B::addOwner(A * owner) 
{ 
    ownerObject = owner; 
} 
 
void B::printOwner() const 
{ 
    ownerObject->print(); //A is complete now, so we can use its member functions 
} 

您可以在 A header 中执行相同的操作。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!