C++ |我怎样才能打破这个 class 间的依赖问题?

C++ | How can I break this inter-class dependency issue?

我提供给你一个MWE:

#include <iostream>


class C;


class A
{
    public:

    A(C &cc)
        : c(cc)
    {
    }

    int functionA()
    {
        return 0;
    }

    C &c;
};


class B
{
    public:

    B(C &cc)
        : c(cc)
    {
    }

    int functionB()
    {
        return c.a.functionA();
    }

    C &c;
};


class C
{
    public:

    C()
        : a(*this)
        , b(*this)
    {
    }

    int functionC()
    {
        return b.functionB();
    }

    A a;
    B b;
};


int main()
{
    C c;
    std::cout << c.functionC() << std::endl;
}

以及相关的编译器错误:

main.cpp: In member function ‘int B::functionB()’:
main.cpp:37:16: error: invalid use of incomplete type ‘class C’
   37 |         return c.a.functionA();
      |                ^
main.cpp:5:7: note: forward declaration of ‘class C’
    5 | class C;
      |       ^

可能不需要进一步解释,但是,当我们到达第 return c.a.functionA() 行时,class C 尚未完全定义。

打破这种相互依存问题的最合适的方法是什么?

如果有帮助指导,再考虑以下上下文

C = Host
A = CPU
B = RAM

而我项目中出现这个问题的实际代码是

void CPU::MemFetchByte(byte &ret, const addr_t addr)
{
    HardwareDevice::host.memory.GetByte(ret, addr);
}

也许这是有用的附加信息,也许不是。

此外,我尝试将问题反转如下

#include <iostream>


//class C;
class A;
class B;



class C
{
    public:

    C()
        : a(new A(*this))
        , b(new B(*this))
    {
    }

    ~C()
    {
        delete b;
        delete a;
    }

    int functionC()
    {
        return b->functionB();
    }

    A *a;
    B *b;
};


class A
{
    public:

    A(C &cc)
        : c(cc)
    {
    }

    int functionA()
    {
        return 0;
    }

    C &c;
};


class B
{
    public:

    B(C &cc)
        : c(cc)
    {
    }

    int functionB()
    {
        return c.a->functionA();
    }

    C &c;
};


int main()
{
    C c;
    std::cout << c.functionC() << std::endl;
}

然而,这(正如预期的那样)使事情变得更糟而不是更好:

main.cpp:16:24: error: invalid use of incomplete type ‘class A’
   16 |         : a(new A(*this))
      |                        ^
main.cpp:6:7: note: forward declaration of ‘class A’
    6 | class A;
      |       ^
main.cpp:17:24: error: invalid use of incomplete type ‘class B’
   17 |         , b(new B(*this))
      |                        ^
main.cpp:7:7: note: forward declaration of ‘class B’
    7 | class B;
      |       ^

通过将构造函数和成员函数实现移出 class 声明来使用完整类型。

#include <iostream>

class A;
class B;
class C;

class A { 
public:
    A(C &cc);
    int functionA();
    C &c; 
};
class B { 
public:
    B(C &cc);
    int functionB();
    C &c; 
};
class C { 
public:
    C();
    int functionC();
    A a;
    B b;
};

int main()
{
    C c;
    std::cout << c.functionC() << std::endl;
}

A::A(C &cc) : c(cc)
{ }

int A::functionA() {
    return 0;
}

B::B(C &cc) : c(cc)
{ }

int B::functionB() {
    return c.a.functionA();
}

C::C() : a(*this), b(*this)
{ }

int C::functionC() {
    return b.functionB();
}
int functionB()
{
    return c.a.functionA();
}

这个函数需要在class体之外定义,class C定义之后


您可以将相同的想法应用到您的第二次尝试中(需要移动 C()~C()functionC() 的定义)。但这比您的第一次尝试更糟糕,因为您无缘无故地使用堆分配(并且 class C 不遵循三的规则)。

看起来 类 AB 是系统 C 的一部分,因此另一种选择是从 [=11] 组成 C =] 和 B 使用推导。这允许 AB 通过简单的向下转换到达 C,不需要 C& c 成员:

struct C;

struct A {
    void fa();
};

struct B {
    void fb();
};

struct C : A, B {
    void fc();
};

void A::fa() {
    static_cast<C&>(*this).fc();
}

void B::fb() {
    static_cast<C&>(*this).fc();
}