为什么复制构造函数不需要检查输入对象是否指向自身?

问题描述 投票:2回答:1

作为下面的代码,复制分配运算符必须检查输入对象是否指向自身。我想知道为什么复制构造函数不需要执行相同的检查。

我是C ++的新手。对于这个问题,我将不胜感激。

  class rule_of_three
    {
        char* cstring; // raw pointer used as a handle to a dynamically-allocated memory block

        void init(const char* s)
        {
            std::size_t n = std::strlen(s) + 1;
            cstring = new char[n];
            std::memcpy(cstring, s, n); // populate
        }
     public:
        rule_of_three(const char* s = "") { init(s); }

        ~rule_of_three()
        {
            delete[] cstring;  // deallocate
        }

        rule_of_three(const rule_of_three& other) // copy constructor
        { 
            init(other.cstring);
        }

        rule_of_three& operator=(const rule_of_three& other) // copy assignment
        {
            if(this != &other) {
                delete[] cstring;  // deallocate
                init(other.cstring);
            }
            return *this;
        }
    };
c++ c++11 constructor copy-constructor assignment-operator
1个回答
1
投票

Self-assignment有时会发生,这是类的正常使用的一部分。

将尚未构造的对象作为参数传递给其自己的副本(或移动)构造函数是不正常的。尽管本身不是未定义的行为1,但没有充分的理由这样做,并且通常不会发生。这可能是偶然发生的,或者是有人故意破坏您的课程。

因此,传统上复制(并移动)构造函数不检查&other != this

但是,如果您需要额外的安全性,没有什么可以阻止您这样做:

rule_of_three(const rule_of_three& other) // copy constructor
{ 
    assert(&other != this);
    init(other.cstring);
}

[[1 [basic.life]/7似乎允许这样做,只要您不访问尚未构造的对象本身即可。允许使用[basic.life]/7获取其地址。


0
投票

假设您有简单的对象,例如突击队:

&

如果要将一个突击队员分配给另一个突击队员,检查两个突击队员是否已经相同(通常是相同的)会很有用。这样就避免了clone()操作,因为Stormtroopers已经完全相同。

但是,如果您要创建一个新的Stormtrooper,并且希望他与另一个Stormtrooper相同(照常),则可以对其进行复制构造,在这种情况下,clone()操作将正确执行。

通过这种方式,您可以很容易地组建一支完整的突击部队。

© www.soinside.com 2019 - 2024. All rights reserved.