系统定义的构造函数与C ++中的用户定义的构造函数

时间:2016-04-16 11:35:16

标签: c++

为什么我们需要定义运算符或复制构造函数,因为这些是系统提供的默认构造函数? 请用例子解释一下

1 个答案:

答案 0 :(得分:2)

当您需要与默认编译器提供的函数实现不同的行为时,您需要提供它们。

默认复制构造函数按值复制所有成员。默认赋值运算符按值分配所有成员。 在很多情况下,这正是您想要的,因此无需提供您自己的实现。但情况并非总是如此。

考虑这个人为的例子:

struct Broken {
  Broken() : i(42), p(new int) { }
  ~Broken() { delete p; }
  int i;
  Int* p;
};

它将获得默认的编译器生成的副本ctor和operator =但在这种情况下它们不能做你想做的事 - 考虑一下:

int main()
{
  Broken b1;
  Broken b2 = b1;
} // you'll probably crash here with a double free

b1在其i成员中存储42,然后在堆上分配新的int并将地址存储在其p成员中(假设地址为0x1234) )。 然后我们从b2构建b1,默认的复制构造函数愉快地将b2.i指定为42 - 这很好。它还指定b2.p具有值0x1234 - 这不是您想要的。现在两个对象都拥有指向同一内存的指针,并且它们的析构函数都将尝试delete它。 因此,当b2超出main末尾的范围时,它会释放内存 - 到目前为止一直很好 - 但是b1也超出范围并试图释放已经释放内存,你的程序现已破裂。

在这种情况下,您需要提供自己的operator =和copy ctor,它们不会天真地复制指针的值,而是复制指针所指向的任何内容并将其存储在新的块中。与原始内存不同的内存,以便两个对象都有自己唯一的副本。

还有很多其他的例子,但这是我能想到的最简单的。