如果类成员是向量,我们是否应该显式编写复制构造函数?

时间:2012-01-25 09:52:07

标签: c++ stl

struct myType {
    vector<char*> ls;
};

此处ls正在指向char。如果未提供myType的用户定义的复制构造函数,myType的默认复制构造函数是否会对ls进行深层复制?

3 个答案:

答案 0 :(得分:8)

  

默认复制构造函数会执行深层复制吗?

当然不是。编译器无法知道谁拥有指向内存。

如果需要深层复制,则必须实施复制构造函数,并将每个char*手动复制到复制到vector中的object的新内存中。

如果您使用char*作为以零终止的字符串,那么您应该真正使用std::string。如果这样做,默认构造函数就足够了。

答案 1 :(得分:8)

  

这里ls是指向char的指针。如果没有提供复制构造函数,默认复制构造函数会执行深层复制吗?

默认的复制构造函数将复制所有成员 - 即调用它们各自的复制构造函数。 1 所以是的,std::vector(就C ++而言并不特别)将是适当的复制。

但是,向量中char*元素指向的内存当然不会,因为C ++不知道并且不关心指针指向的内容。

但这里的解决方案不是提供自定义复制构造函数。这是使用数据结构而不是原始指针(char*。这恰好是std::string(或std::vector<char>,具体取决于意图)。


1 因此创建了复制操作的传递闭包 - 这就是通常实现深度复制的方式,但当然复制操作的实现者总是可以突破它的。

答案 2 :(得分:2)

不,它不会。

C ++将递归调用所有子对象的copy ctor。因此,它将调用向量的副本ctor,后者将调用char*的副本ctor,它将按值char*复制std::string。 C ++永远不会自动分配内存并复制数据。它甚至不可能这样做,因为它不知道你指向的数据是什么,以及它应该复制多少。

当您使用字符串时,您应该更喜欢使用{{1}},因为这将为您完成所有复制。如果它是一些需要特殊处理的二进制数据缓冲区,那么你需要在你的复制文件中自己完成(当你完成后,想一想,考虑要求C ++为你做这件事是否真的明智)

当您编写自己的副本时,您始终应该注意Rule of Three