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
不遵循三的规则)。
看起来 类 A
和 B
是系统 C
的一部分,因此另一种选择是从 [=11] 组成 C
=] 和 B
使用推导。这允许 A
和 B
通过简单的向下转换到达 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();
}
我提供给你一个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
不遵循三的规则)。
看起来 类 A
和 B
是系统 C
的一部分,因此另一种选择是从 [=11] 组成 C
=] 和 B
使用推导。这允许 A
和 B
通过简单的向下转换到达 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();
}