首页 > 解决方案 > 为什么复制构造函数不需要检查输入对象是否指向自身?

问题描述

如下代码所示,复制赋值运算符必须检查输入对象是否指向自身。我想知道为什么复制构造函数不需要做同样的检查。

我是 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++11constructorcopy-constructorassignment-operator

解决方案


分配有时会发生,这是正常使用课程的一部分。

将尚未构造的对象作为参数传递给它自己的复制(或移动)构造函数是不正常的。虽然本身不​​是未定义的行为1,但没有充分的理由这样做,而且通常不会发生。它可能会意外发生,或者如果有人故意试图破坏您的课程。

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

但是,如果您想要一些额外的安全性,没有什么能阻止您这样做:

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

1 [basic.life]/7似乎允许这样做,只要您不访问尚未构建的对象本身。&允许使用它的地址


推荐阅读