如何在没有 headers 的情况下解决共享基础 class 的循环 class 依赖?
How to solve a circular class dependency with shared base class without headers?
所以我正在创建一个项目,其中涉及将向量相互嵌套,但该结构无法编译。我认为这是循环依赖的情况,但我看到的所有修复似乎只适用于涉及 header 文件和单独翻译单元的代码。
#include <iostream>
#include <vector>
class A {
public:
virtual ~A();
};
// The following forward declaration statements didn't solve the
// compiler error:
// class C;
// class C : public A;
class B : public A {
std::vector<A*> Avector;
public:
void addC(C* Cin){Avector.push_back(Cin);}
~B();
};
class C : public A {
std::vector<A*> Avector;
public:
void addB(B* Bin){Avector.push_back(Bin);}
~C();
};
int main() {
B b;
C c;
b.addC(&c);
c.addB(&b);
}
我已经尝试使用
进行前向声明
class C;
Class C : public A;
但是 none 似乎有效。
我得到的错误是:
\test\test\source.cpp(15): error C2061: syntax error : identifier 'C'
\test\test\source.cpp(15): error C2065: 'Cin' : undeclared identifier
这种代码可以实现吗?
"... but all of the fixes I've seen seem to only apply to code involving header files and separate translation units."
我非常同意像 Resolve circular dependencies in c++ 这样的流行问答并没有真正回答您如何在单个实现文件中处理这个问题 (header或不)。
但是恕我直言,将 header 和 implementation/definition 中的 class 声明分开被认为是更好的做法(您可以通过 these pointers 了解)他们自己的翻译单位。
即使仅使用 header(例如模板 class)库,您也应该考虑提供单独的 class 声明(没有内联代码),并在单独的源文件中提供实现,包括在内那里。
你的问题其实在这里:
class B : public A {
// ...
void addC(C* Cin) { Avector.push_back(Cin); }
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ...
};
此时(即使有class C;
的前向声明)编译器不知道如何将C*
转换为A*
,因为关于继承关系的信息是缺失(不,你不能做出像 class C : public A;
这样的前向声明)。
"Is this sort of code implementable?"
您可以在一次翻译中完成所有这些 unit/header 文件:
与其将函数定义与 B
的 class 声明内联,不如将其分离出来以便在 class C
:
的完整声明之后看到
class C;
class B : public A {
// ...
void addC(C* Cin);
};
class C : public A {
// ...
};
inline void B::addC(C* Cin) { Avector.push_back(Cin); }
class C
无论如何都会看到 class B
的完整声明(因为声明顺序)。因此可以使用 implementation
void addB(B* Bin) { Avector.push_back(Bin); }
来自 class C
声明。
我试过前向声明,我试过将函数实现放在第二部分之后,但我没有同时尝试过。 10 年后任何人谷歌搜索的固定代码:
#include<iostream>
#include<vector>
using namespace std;
class C;
class A
{
public:
virtual ~A();
};
class B : public A
{
public:
vector<A*> Avector;
void addC(C* Cin);
~B();
};
class C : public A
{
public:
vector<A*> Avector;
void addB(B* Bin)
{
Avector.push_back(Bin);
};
~C();
};
void B::addC(C* Cin)
{
Avector.push_back(Cin);
}
int main()
{
}
感谢 πìντα ῥεῖ ,并向 Jarod42 致敬。
所以我正在创建一个项目,其中涉及将向量相互嵌套,但该结构无法编译。我认为这是循环依赖的情况,但我看到的所有修复似乎只适用于涉及 header 文件和单独翻译单元的代码。
#include <iostream>
#include <vector>
class A {
public:
virtual ~A();
};
// The following forward declaration statements didn't solve the
// compiler error:
// class C;
// class C : public A;
class B : public A {
std::vector<A*> Avector;
public:
void addC(C* Cin){Avector.push_back(Cin);}
~B();
};
class C : public A {
std::vector<A*> Avector;
public:
void addB(B* Bin){Avector.push_back(Bin);}
~C();
};
int main() {
B b;
C c;
b.addC(&c);
c.addB(&b);
}
我已经尝试使用
进行前向声明class C;
Class C : public A;
但是 none 似乎有效。
我得到的错误是:
\test\test\source.cpp(15): error C2061: syntax error : identifier 'C'
\test\test\source.cpp(15): error C2065: 'Cin' : undeclared identifier
这种代码可以实现吗?
"... but all of the fixes I've seen seem to only apply to code involving header files and separate translation units."
我非常同意像 Resolve circular dependencies in c++ 这样的流行问答并没有真正回答您如何在单个实现文件中处理这个问题 (header或不)。
但是恕我直言,将 header 和 implementation/definition 中的 class 声明分开被认为是更好的做法(您可以通过 these pointers 了解)他们自己的翻译单位。
即使仅使用 header(例如模板 class)库,您也应该考虑提供单独的 class 声明(没有内联代码),并在单独的源文件中提供实现,包括在内那里。
你的问题其实在这里:
class B : public A {
// ...
void addC(C* Cin) { Avector.push_back(Cin); }
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ...
};
此时(即使有class C;
的前向声明)编译器不知道如何将C*
转换为A*
,因为关于继承关系的信息是缺失(不,你不能做出像 class C : public A;
这样的前向声明)。
"Is this sort of code implementable?"
您可以在一次翻译中完成所有这些 unit/header 文件:
与其将函数定义与 B
的 class 声明内联,不如将其分离出来以便在 class C
:
class C;
class B : public A {
// ...
void addC(C* Cin);
};
class C : public A {
// ...
};
inline void B::addC(C* Cin) { Avector.push_back(Cin); }
class C
无论如何都会看到 class B
的完整声明(因为声明顺序)。因此可以使用 implementation
void addB(B* Bin) { Avector.push_back(Bin); }
来自 class C
声明。
我试过前向声明,我试过将函数实现放在第二部分之后,但我没有同时尝试过。 10 年后任何人谷歌搜索的固定代码:
#include<iostream>
#include<vector>
using namespace std;
class C;
class A
{
public:
virtual ~A();
};
class B : public A
{
public:
vector<A*> Avector;
void addC(C* Cin);
~B();
};
class C : public A
{
public:
vector<A*> Avector;
void addB(B* Bin)
{
Avector.push_back(Bin);
};
~C();
};
void B::addC(C* Cin)
{
Avector.push_back(Cin);
}
int main()
{
}
感谢 πìντα ῥεῖ ,并向 Jarod42 致敬。