Rule of Three
Sometimes you need to implement a class that manages a resource. (Never manage multiple resources in a single class, this will only lead to pain.) In that case, remember the rule of three:
If you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them
class Foo
{
char* _text;
public:
// Regular constructor
Foo(const char* text) : _text(new char[std::strlen(text) + 1])
{
std::strcpy(_text, text);
}
// Copy constructor
Foo(const Foo& other)
{
_text = new char[std::strlen(other._text) + 1];
std::strcpy(_text, other._text);
}
// Destructor
~Foo()
{
delete[] _text;
}
// Copy operator
Foo& operator=(Foo other)
{
std::swap(_text, other._text);
return *this;
}
};
NOTE: A good implementation also uses a custom swap function
Rule of Five
class Foo
{
char* _text;
public:
// Regular constructor
Foo(const char* text) : _text(new char[std::strlen(text) + 1])
{
std::strcpy(_text, text);
}
// Copy constructor
Foo(const Foo& other)
{
_text = new char[std::strlen(other._text) + 1];
std::strcpy(_text, other._text);
}
// Move constructor
Foo(Foo&& other) : _text(other._text)
{
other._text = nullptr;
}
// Destructor
~Foo()
{
delete[] _text;
}
// Copy operator
Foo& operator=(Foo other)
{
std::swap(_text, other._text);
return *this;
}
};
Reference: The rule of three/five/zero