Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does copy constructor not need to check whether the input object pointers to itself or not?

As the code below, the copy assignment operator has to check whether the input object pointers to itself or not. I wonder why copy constructor does not need to do the same check.

I am novice in C++.I would be grateful to have some help on this question.

  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;
        }
    };
like image 202
sunshilong369 Avatar asked Sep 16 '25 23:09

sunshilong369


1 Answers

Self-assignment sometimes happens, it's a part of a normal use of a class.

Passing a not-yet-constructed object as a parameter to its own copy (or move) constructor is not normal. While not undefined behavior per se1, there are no good reasons to do it, and it normally doesn't happen. It can happen accidentally, or if someone is deliberately trying to break your class.

Because of that, traditionally copy (and move) constructors don't check for &other != this.

But nothing stops you from doing it, if you want some extra safety:

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

1 [basic.life]/7 seems to allow that, as long as you don't access the not-yet-constructed object itself. Taking an address of it using & is allowed.

like image 64
HolyBlackCat Avatar answered Sep 19 '25 12:09

HolyBlackCat