A -> B, B -> A 类关联

A -> B, B -> A classes association

本文关键字:gt 关联      更新时间:2023-10-16

这段代码不做任何特别的事情。它只是一个片段,用于显示前向声明的问题。只是一个简短的问题:为什么它不起作用以及如何强制它工作?

class A;
class B {
    A obj;
public:
    int getB() const {
        return 0;
    }
    void doSmth() {
        int a = obj.getA();
    }
};
class A {
    B obj;
public:
    int getA() const {
        return 1;
    }
    void doSomething() {
        int b = obj.getB();
    }
};

这段代码给了我错误:

error C2079: 'B::obj' uses undefined class 'A'
error C2228: left of '.getA' must have class/struct/union

前向声明只允许您使用指针和对对象的引用。您正在尝试在类定义可用之前完全定义一个。

要做到这一点,你应该将 A 中的 obj 更改为指针(可能不是最好的解决方案)或使用 PIMPL 习语(谷歌它),这应该可以让您解决此问题。

你的构造根本没有意义。AB 都不是定义明确的结构,因为它们包含无限递归的子对象序列。

您刚刚提出了一个与此相同的问题的稍微模糊的示例:

struct Box { Box hubert; };

同样,这种数据结构毫无意义。

如果你愿意的话,编程中的所有内容都必须是有限的和有根据的。


实际上,C++通过要求类定义必须仅包含具有完整类型的成员对象来禁止您尝试执行的操作。但它只是归结为逻辑意义。想想如何初始化这样的数据结构。有些事情总是要放在第一位的。

这种类型的

循环依赖在C++是不可能的。不能让对象相互包含。但是,您可以存储指针或引用。如果没有完整的定义,您也不能真正使用类的方法。

因此,您需要做两件事:

1) 将对象替换为指针。

2) 在类定义之后实现方法。如果它们位于标头中,则需要将它们标记为inline以防止多个定义。

class A;
class B {
    std::shared_ptr<A> obj;
public:
    int getB() const;
    void doSmth();
};
class A {
    std::shared_ptr<B> obj;
public:
    int getA() const;
    void doSomething();
};

inline int B::getB() const {
        return 0;
    }
inline void B::doSmth() {
        int a = obj->getA();
    }

inline int A::getA() const {
        return 1;
    }
inline void A::doSomething() {
        int b = obj->getB();
    }

我认为您需要为 obj A 和 obj B 创建头文件来解决您的问题。当定义 B 时,它只知道 A 存在,不知道 A 有什么函数/方法。

每个

头文件都需要包含每个函数/方法的原型。例:

class A{
   int GetA() const;
   void DoSomething();
}

格式可能已关闭(我习惯了 Obj C 标头),但这应该会有所帮助。