We can combine the principles of the Rule of Five and RAII to get a much leaner interface: the Rule of Zero: any resource that needs to be managed should be in its own type. That type would have to follow the Rule of Five, but all users of that resource do not need to write any of the five special member functions and can simply default
all of them.
Using the Person
class introduced in the Rule of Three example, we can create a resource-managing object for cstrings
:
class cstring {
private:
char* p;
public:
~cstring() { delete [] p; }
cstring(cstring const& );
cstring(cstring&& );
cstring& operator=(cstring const& );
cstring& operator=(cstring&& );
/* other members as appropriate */
};
And once this is separate, our Person
class becomes far simpler:
class Person {
cstring name;
int arg;
public:
~Person() = default;
Person(Person const& ) = default;
Person(Person&& ) = default;
Person& operator=(Person const& ) = default;
Person& operator=(Person&& ) = default;
/* other members as appropriate */
};
The special members in Person
do not even need to be declared explicitly; the compiler will default or delete them appropriately, based on the contents of Person
. Therefore, the following is also an example of the rule of zero.
struct Person {
cstring name;
int arg;
};
If cstring
were to be a move-only type, with a delete
d copy constructor/assignment operator, then Person
would automatically be move-only as well.
The term rule of zero was introduced by R. Martinho Fernandes