因此,我正在阅读C ++中的一段文本,并遇到了以下代码:
class example
{
int dataMember;
public:
example& assign(const example& source)
{
if(this!=&source)
{
this->~example();
new (this) example(source);
}
}
};
好的,我正在尝试解码此函数分配正在执行的操作。我所了解的:
该函数接受类实例的常量引用,并返回对该类的引用。
在该if
块内部,首先为当前实例调用析构函数(据我所知,当前对象已销毁并释放了内存)。
现在的主要问题是:
new (this) example(source)
这条线令我困扰。这是怎么回事 如果我被要求猜测,我会说正在创建一个新对象并将其分配为当前对象,正如我可以从this
关键字推断的那样。
谁能解决这个问题?这里到底发生了什么事?
这种方法安全吗?(如果分配是动态发生的,程序员将来必须手动取消分配)
谢谢。
您看到的是尝试重用代码。这个想法是使用复制构造函数来实现赋值运算符(或在本例中为赋值函数)。
首先,要摆脱简单的东西:
在if
确保了自赋值(例如x.assign(x)
)正被正确处理。这是必要的,因为实现依赖于一个事实,即改变*this
不会改变source
。通过与this
另一个对象的地址进行比较,这确实测试了对象是否相等,但是否相同。
该函数缺少return *this;
,但您可能已经注意到了。
现在到剩下的两行:
this->~example();
显式调用该类的析构函数example
。在该行之后,this
指针不再指向对象,而是指向的未初始化内存sizeof(example)
。
new (this) example(source);
就是所谓的放置新的,这并没有分配内存,而是简单地创建一个新example
的位置指向this
通过调用拷贝构造函数。从某种意义上讲,这是显式调用构造函数而不分配任何内存的语法。
请注意,*this
无论在哪里,它都将重用先前保存的内存:它甚至可以是例如virtual
动态分配的数组的元素的基础...
关于安全性:在实践中,只要构造函数和析构函数均不抛出异常,这是安全的(尽管很丑,而且可能不是很有效)。但是,从试图像这样的偷偷摸摸的类派生时,您可能会遇到问题。
如果您想知道编写重用复制构造函数的赋值运算符/函数的最简单方法,请检查此问题,基本上可以归结为:
example& assign(example source)
{
swap(*this, source);
return *this;
}
最重要的区别:
swap
则此代码是异常安全的,并且是异常安全的(应始终如此)。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句