考虑以下示例:
a.h
:
#ifndef A_H
#define A_H
#include <vector>
#include <memory>
#include "b.h"
enum class SActionType;
class A {
std::vector<std::unique_ptr<B>> my_bees;
public:
A();
void print(int x, int y);
};
#endif
a.cc
:
#include <iostream>
#include "a.h"
A::A() {
}
void A::print(int x, int y) {
std::cout << "hi this is not going to work" << std::endl;
}
b.h
:
#ifndef B_H
#define B_H
#include <memory>
#include <vector>
// #include "a.h"
class A;
class B {
std::shared_ptr<A> a;
public:
B(std::shared_ptr<A> a);
void foo();
};
#endif
b.cc
:
#include <algorithm>
#include "b.h"
B::B(std::shared_ptr<A> a):
a{a}
{}
void B::foo() {
a->print(1, 2);
}
main.cc
:
#include "a.h"
#include "b.h"
int main() {
return 0;
}
Makefile
:
exec: main.o a.o b.o
g++ -std=c++14 -o exec
main.o: main.cc
a.o: a.cc a.h
b.o: b.cc b.h
运行make
后,出现以下错误:
me:~$ make
g++ -c -o b.o b.cc
b.cc: In member function ‘void B::foo()’:
b.cc:9:6: error: invalid use of incomplete type ‘using element_type = class A {aka class A}’
a->print(1, 2);
^~
In file included from b.cc:2:0:
b.h:8:7: note: forward declaration of ‘using element_type = class A {aka class A}’
class A;
^
<builtin>: recipe for target 'b.o' failed
make: *** [b.o] Error 1
为什么会这样?我认为这是可行的,因为类B
实际上不需要访问A的成员函数,直到.cc
文件为止,仅在头文件中包含前向声明就足以规避循环依赖。
答案 0 :(得分:3)
我认为这是可行的,因为类
B
实际上不需要访问A
的成员函数,直到.cc
文件
是的。 b.h
不需要包含a.h
(a.h
也不需要包含b.h
)。但是b.cc
需要同时包含两者。对此没有任何通知。毕竟,a.cc
做同样的事情。
b.cc
#include <algorithm>
#include "a.h"
#include "b.h"
B::B(std::shared_ptr<A> a):
a{a}
{}
void B::foo() {
a->print(1, 2);
}
答案 1 :(得分:0)
编译器需要知道要检查这种构造的A类的完整类型
void B::foo() {
a->print(1, 2);
}
有效的是类A包含成员函数(静态还是非静态的)print
。