通过新操作符使用列表初始化

背景

请考虑以下代码段:

MyClass * p1 = new MyClass;
p1->data = 1;
MyClass c2 = MyClass();
p2.data = 2;
new(p1) MyClass {c2};
cout << p1.data;

其中MyClass仅包含单个公共成员int data

前4行很简单:我们创建了两个MyClass对象,一个使用new,另一个不使用。下一行发生的事情是将c2的内容复制到p1中,这意味着最后一行的输出为2

我的问题是关于new(p1) MyClass {c2};行上到底发生了什么。我的理解是,有两个操作:new和列表初始化程序。对于基于thisnew,如果您以指针作为参数调用new,则它不会分配任何新的内存,而只是在给定的位置构造一个对象指针,该指针是new运算符的返回值。这意味着new(p1) MyClass解析为一个指向与p1相同地址的指针。然后,使用列表初始化{c2}p1的内容设置为c2,这就是为什么末尾的输出为2而不是1的原因

问题:

这是对正在发生的事情的正确理解吗?

如果是这样,我有一个困惑点,就是new运算符new(p1) MyClass应该解析为一个指针,但是看起来我们正在分配c2而不是指针,而是整个MyClass对象。这是怎么回事?

最后,我想知道使用此语法背后的动机是什么。我是C语言的新手,在C语言中,您只需要编写类似*p1 = c2;的内容即可完成与new(p1) MyClass {c2};

相同的任务
iCMS 回答:通过新操作符使用列表初始化

您要提出的问题涉及多种因素。主要的两件事是

  • 3的规则(如果包含现代c ++的移动语义,则为5大规则)
  • 内存管理

首先,当您使用 new 关键字时,它用于通过分配内存然后构造它来在Free Store / Heap区域中创建对象。即使在程序终止后,此处创建的对象仍保留在此处,必须使用关键字删除将其删除。 按照这种逻辑, p1 对象存储在免费存储中。

关于第五行的前半部分

new(p1) 

这种对new的使用不会分配内存,但实际上会在 p1 的位置构造对象。

下半场...

MyClass {c2};

负责调用对象的构造函数,并根据c2的属性构造该对象(也称为复制构造函数)。 举一个很好的例子,这是c ++中新操作符的文档链接:http://www.cplusplus.com/reference/new/operator%20new/

复制构造函数的这一思想是 3规则的一部分,该规则如下:

  • 析构函数(调用销毁对象的函数)
  • 复制构造函数(第5行中用于创建新对象的东西)
  • 复制分配运算符(重载=运算符以创建新函数,即Obj1 = Obj 2)。

我建议研究这些概念,以进一步了解C ++中的对象行为。其中大多数已为C ++中的所有对象预定义。但是,您始终可以覆盖其中的任何一个以满足您的对象需求。

重要说明::如果您覆盖C ++给您的任何默认big 3,则您都必须覆盖所有它们,因为可能存在差异。 这是一个很好的幻灯片平台,可帮助您深入探讨Big 5的主题(其他两个主题与现代C ++中的移动语义有关,但前三个幻灯片主题详细介绍了Big 3):https://www.feabhas.com/sites/default/files/2016-06/Rule%20of%20the%20Big%20Five.pdf >

本文链接:https://www.f2er.com/1780343.html

大家都在问