如果我创建一个这样的类:
// B.h #ifndef _B_H_ #define _B_H_ class B { private: int x; int y; }; #endif // _B_H_
并像这样使用它:
// main.cpp #include#include class B; // Forward declaration. class A { public: A() { std::cout << v.size() << std::endl; } private: std::vector v; }; int main() { A a; }
编译时编译器失败main.cpp
.现在我知道的解决方案是#include "B.h"
,但我很好奇为什么它失败了.无论是g++
或cl
的错误信息都在这个问题很有启发.
编译器在生成适当的布局信息之前需要知道"B"有多大.相反,如果你说std::vector
,那么编译器就不需要知道B有多大,因为它知道指针有多大.
实际上,如果A的构造函数是在知道B类型的编译单元中实现的,那么您的示例将构建.
std :: vector实例具有固定的大小,无论T是什么,因为它包含,如前所述,只包含指向T的指针.但是vector的构造函数取决于具体类型.您的示例无法编译,因为A()尝试调用向量的ctor,如果不知道B就无法生成.这是可行的:
A的声明:
// A.h #includeclass B; // Forward declaration. class A { public: A(); // only declare, don't implement here private: std::vector v; };
A的实施:
// A.cpp #include "A.h" #include "B.h" A::A() // this implicitly calls vector's constructor { std::cout << v.size() << std::endl; }
现在A的用户只需知道A,而不是B:
// main.cpp #include "A.h" int main() { A a; // compiles OK }
要实例化A :: v,编译器需要知道B的具体类型.
如果您想尽量减少#included行李的数量以改善编译时间,那么您可以做两件事,它们实际上是彼此的变化:
使用指向B的指针
使用轻量级代理 B