By default in C++, many methods are included by the compiler (i.e., the default constructor). But we may often have to implement our own methods. If a class requires one of the following, then it requires all of these 3.

Think about where we might have to implement all three: when there are memory-based elements within the class, like dynamic memory allocation or pointers. Where this occurs, we need a way to be able to de-allocate memory or ensure objects are independent.

Take the example below:

// copy constructor
MyString::MyString (const MyString& x) {
	len = x.len;
	buf = new char[len + 1];
	strcpy(buf, x);
}
// destructor
MyString::~MyString() {
	if (buf != nullptr) {
		delete [] buf;
		buf = nullptr;
	}
}
// assignment operator
MyString& MyString::operator=(const MyString& src) {
	delete [] buf;
	buf = new char[strlen(src) + 1]
	strcpy(buf, src.buf);
	len = src.len;
	return *this;
}

Take the inverse case. If all of the class’s fields aren’t pointers and/or are default types in C++, then the compiler-generated three methods will suffice. This is called the rule of zero.