为什么不能将向前声明用于std :: vector?
时间:2020-03-05 18:45:47 来源:igfitidea点击:
如果我像这样创建一个类:
// B.h #ifndef _B_H_ #define _B_H_ class B { private: int x; int y; }; #endif // _B_H_
并像这样使用它:
// main.cpp #include <iostream> #include <vector> class B; // Forward declaration. class A { public: A() { std::cout << v.size() << std::endl; } private: std::vector<B> v; }; int main() { A a; }
编译main.cpp
时编译器失败。现在我知道的解决方案是" #include" B.h",但是我很好奇它为什么失败。在这件事上,
g ++或者
cl`的错误信息都不是非常有启发性的。
解决方案
回答
要实例化A :: v,编译器需要知道B的具体类型。
如果我们想尽量减少#included行李的数量以提高编译时间,则可以做两件事,它们实际上是彼此不同的:
- 使用指向B的指针
- 对B使用轻量级代理
回答
编译器在生成适当的布局信息之前需要知道" B"有多大。相反,如果我们说std :: vector <B *>
,则编译器将不需要知道B的大小,因为它知道指针的大小。
回答
之所以不能使用前向声明,是因为B的大小未知。
在示例中没有理由不能将B.h包含在A.h中,那么我们到底要解决什么问题?
编辑:还有另一种方法可以解决此问题:停止使用C / C ++!到了1970年代...;)
回答
它不仅仅是需要的B的大小。例如,现代的编译器会花哨的技巧来使用memcpy加快矢量副本的速度。这通常是通过部分专注于元素类型的POD来实现的。根据前向声明,我们无法判断B是否是POD。
回答
不管使用矢量还是尝试实例化一个B都无关紧要。实例化需要对象的完整定义。