【发布时间】:2019-09-18 08:51:16
【问题描述】:
我有两个类都必须互相调用公共方法。问题是必须首先定义其中一个类。因此,当我定义一个类时,它必须调用另一个尚未定义的类的方法。 B 类的前向声明也无济于事。这样编译器只知道类 B 存在,但不知道它有哪些成员。但是当 changeB() 被定义时,编译器需要知道它们。
这里是一个简化的例子
#include <iostream>
class B;
class A {
public:
B* b;
int data = 0;
void changeB(){
b->data = 5;
}
};
class B {
public:
A* a;
int data = 0;
void changeA(){
a->data = 5;
}
};
int main(int argc, char const *argv[]) {
A a;
B b;
a.b = &b;
b.a = &a;
a.changeB();
b.changeA();
std::cout << "a.data: " << a.data << std::endl;
std::cout << "b.data: " << b.data << std::endl;
return 0;
}
当我编译这个(Windows 10 下的 clang++)时,我得到了
.\CrossClassAccess.cpp:12:14: error: member access into incomplete type 'B'
b->data = 5;
^
.\CrossClassAccess.cpp:3:7: note: forward declaration of 'B'
class B;
^
1 error generated.
在我做了这个简单的例子之后,我想如果我先声明两个类然后定义方法可能会有所帮助。直到某一点,它帮助并显示了预期的解决方案。
#include <iostream>
class B;
class A {
public:
B* b;
int data = 0;
void changeB();
};
class B {
public:
A* a;
int data = 0;
void changeA();
};
void A::changeB(){
b->data = 5;
}
void B::changeA(){
a->data = 5;
}
// main() is still the same
但我想让这更接近现实,以了解为什么这在我的实际项目中不起作用。所以我把文件分成一个主文件、两个cpp文件和两个头文件。在此之后,它不再起作用了。
CrossClassAccessMain.cpp
#include <iostream>
#include "CrossClassAccessA.hpp"
#include "CrossClassAccessB.hpp"
int main(int argc, char const *argv[]) {
A a;
B b;
a.b = &b;
b.a = &a;
a.changeB();
b.changeA();
std::cout << "a.data: " << a.data << std::endl;
std::cout << "b.data: " << b.data << std::endl;
return 0;
}
CrossClassAccessA.hpp
class B;
class A {
public:
B* b;
int data = 0;
void changeB();
};
CrossClassAccessB.hpp
class A;
class B {
public:
A* a;
int data = 0;
void changeA();
};
CrossClassAccessA.cpp
#include "CrossClassAccessA.hpp"
void A::changeB(){
b->data = 5;
}
CrossClassAccessB.cpp
#include "CrossClassAccessB.hpp"
void B::changeA(){
a->data = 5;
}
当我编译这个时,我再次得到这个错误
.\CrossClassAccessA.cpp:4:6: error: member access into incomplete type 'B'
b->data = 5;
^
./CrossClassAccessA.hpp:1:7: note: forward declaration of 'B'
class B;
^
1 error generated.
.\CrossClassAccessB.cpp:4:6: error: member access into incomplete type 'A'
a->data = 5;
^
./CrossClassAccessB.hpp:1:7: note: forward declaration of 'A'
class A;
^
1 error generated.
我用来编译的命令是
clang++ .\CrossClassAccessMain.cpp .\CrossClassAccessA.cpp .\CrossClassAccessB.cpp
当我更改 CrossClassAccessA 和 CrossClassAccessB 的顺序时,我得到了同样的错误,只是顺序颠倒了。
对我来说,看起来一个 cpp 文件是在解析另一个头文件之前编译的。
那么,即使我拆分了我的代码,我如何才能按照我的示例的工作顺序来执行编译过程到不同的文件中?
对于这个例子,我使用的是 clang++。在我的主要项目中,我使用的是 Arduino,并使用 arduino_debugger.exe 通过命令行对其进行编译。我认为在后端它使用的是 avr-gcc 编译器。我不确定是否可以将编译器标志传递给 arduino_debugger.exe。如果不是(我很确定),我也可以直接使用 avr-gcc 编译它(但它不像使用 arduino_debugger.exe 那样简单)。
【问题讨论】:
-
你不应该在
B和A中的#include "CrossClassAccessA.hpp"和A中也一样吗? -
您必须在
CrossClassAccessA.cpp中输入#include "CrossClassAccessB.hpp"(对于其他源文件也是如此)。 -
这在不重要的地方有帮助,在它所在的地方没有帮助。在 molbdnilo 的回答下查看我的评论。