实施课堂作业

阿克沙伊·阿罗拉(Akshay Arora)

因此,我正在阅读C ++中的一段文本,并遇到了以下代码:

class example
{
    int dataMember;

public:
    example& assign(const example& source)
    {
        if(this!=&source)
        {
            this->~example();
            new (this) example(source);
        }


    }

};

好的,我正在尝试解码此函数分配正在执行的操作。我所了解的:

  1. 该函数接受类实例的常量引用,并返回对该类的引用。

  2. 在该if内部,首先为当前实例调用析构函数(据我所知,当前对象已销毁并释放了内存)。

现在的主要问题是:

new (this) example(source)

这条线令我困扰。这是怎么回事 如果我被要求猜测,我会说正在创建一个新对象并将其分配为当前对象,正如我可以从this关键字推断的那样

谁能解决这个问题?这里到底发生了什么事?

这种方法安全吗?(如果分配是动态发生的,程序员将来必须手动取消分配)

谢谢。

ha

您看到的是尝试重用代码。这个想法是使用复制构造函数来实现赋值运算符(或在本例中为赋值函数)。

首先,要摆脱简单的东西:

  • 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;
}

最重要的区别:

  • 它在适用的情况下利用move构造函数。
  • 如果复制/移动构造函数,swap此代码是异常安全的,并且是异常安全的(应始终如此)。
  • 自我分配的效率稍低,因为它将执行复制,而不是识别自我分配。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章