![]() |
1
7
你不能。编译器在声明类时需要知道对象的大小。 引用是一种替代方案,尽管它们必须在构造时实例化,因此并不总是可行的。 另一种选择是智能指针,但我认为从技术上讲,它仍然是一个指针。 不过,最好知道为什么你不想使用指针来建议其他构造。.. |
![]() |
2
12
只需使用智能指针——在这种情况下,您甚至可以使用auto_ptr。
您可以获得自动内存管理的所有好处,而无需了解bar.h中的foo。请参阅 Wrapping Pointer Data Members 感谢赫伯·萨特的推荐。 如果你真的希望默认构造自动发生,请尝试以下操作:
|
![]() |
3
7
你想要的东西在C++中是做不到的。为了为对象生成代码,编译器需要知道其类需要多少存储空间。为了知道这一点,它必须知道类的每个成员需要多少存储空间。 如果你想创建一个包含foo类型成员的bar类型的类,编译器必须知道foo有多大。它知道这一点的唯一方法是它是否有foo的定义(通过#include)。否则,您唯一的选择就是使用foo的前向声明和指针或引用,而不是实际的foo对象。 |
![]() |
4
2
正如其他人所说,你不能这样做,因为他们也说:)然后你说你不想关心包含它们的类中的成员构造/销毁。您可以为此使用模板。
我认为代码是不言自明的。如果有任何问题,请打扰我。 |
![]() |
5
1
这是没有办法的。 你最好的办法是限制包含的内容,但你必须在类声明中包含文件。您可以将类声明拆分为一个单独的标头,希望其中不包含其他内容。然后,是的,你必须有一个#include,但你仍然让你的include层次结构有点浅。毕竟,包含一个文件很便宜,只有当层次结构扩展到数百或数千个文件时,它才会开始受到伤害。.. ;) |
![]() |
6
1
几乎你唯一能做的就是通过以下方式尽量减少影响 using the pImpl idiom 因此,当你包含foo.h时,你只包含foo的接口。 你无法避免包含foo.h,但你可以让它尽可能便宜。你养成了使用向前声明而不是#includes的习惯,这让你在这条路上走得很好。 |
![]() |
7
0
如果能够使用引用,则可以保留相同的使用语法。然而,你的引用必须在构造函数中立即初始化,所以你的ctor绝对必须被定义得不符合要求。(您还需要释放析构函数中的对象。)
您的里程数可能会有所不同。 :-) |
![]() |
8
0
您可以使用一个自定义的“智能指针”类,该类可以自动创建和销毁实例。这将实现您所追求的自动构建和销毁。
为了防止需要另一个#include,您可以包含以下内容
以下是您将如何使用它:
|
![]() |
9
0
你也可以使用pImpl习语,例如:
您仍然可以获得正向声明的好处,并且可以隐藏您的私有实现。对bar实现的更改不一定需要编译所有包含bar.h的源文件。实现结构本身在.cpp文件中是自包含的,在这里你可以向你的heart内容声明对象。 由于pImpl本身,您的性能受到了轻微的影响,但根据应用程序的不同,这可能不是什么大问题。 我曾将pImpl习惯用法用于大型项目,这对编译时间有很大影响。遗憾的是,该语言无法处理真正的私有实现,但你已经拥有了它。 |
![]() |
10
0
实际上只有三种方法可以关联两个对象。 你已经发现了两种方法:在Bar中嵌入Foo,或者把Foo放在堆上,然后在Bar中放一个Foo*。第一个要求在定义类Bar之前定义类Foo;第二个只需要你转发声明类Foo。
第三种选择确实存在,我之所以提到它,是因为你在问题中明确排除了前两种选择。您可以(在.cpp中)创建一个静态std::map。在每个Bar构造函数中,你都会向这个映射添加一个Foo,并键入
虽然这使sizeof(Bar)保持不变,但实际的内存使用量高于在Bar中包含Foo*。不过,如果二进制兼容性是一个紧迫的问题,您仍然可以这样做。 |