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

System defined Constructors Vs user defined constructors in C++

本文关键字:构造函数 定义 用户 系统 C++      更新时间:2023-10-16

为什么我们需要定义运算符或复制构造函数,因为它们是系统提供的默认构造函数?请用

的例子来解释这一点

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

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

考虑一下这个人为的例子:

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)。然后,我们从b1构造b2,默认的复制构造函数愉快地将b2.i赋值为42——这很好。它还指定b2.p的值为0x1234——这不是您想要的。现在,两个对象都持有指向同一内存的指针,并且它们的析构函数都将尝试delete它。因此,当b2main结束时超出范围时,它会处理内存——到目前为止还不错——但随后b1也超出范围,并试图释放已经释放的内存,而您的程序现在已损坏。

在这种情况下,您可能希望提供自己的运算符=和复制ctor,它们不会天真地复制指针的值,而是对指针指向的任何对象进行深度复制,并将其存储在与原始对象不同的新内存块中,这样两个对象都有自己的唯一副本。

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