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;
}
};
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With