I cannot remember the rules according to which C++ automatically generates some class members, so this note serves as a reminder.
The rules for automatically generating class members for a class T are:
A copy constructor (which takes a single argument of type const T &) is generated if all base classes and members are copy-constructible. Note that reference members are copy-constructible.
The parameter-less default constructor is generated if the class does not define any constructor and all base classes and members are default-constructible. This means that once you declare a copy constructor (perhaps to disable the automatically provided one, see below), the compiler will not supply a default construtor.
The copy-assignment operator T &T::operator=(const T &) is generated if all base classes and members are copy-assignable. For this purpose, reference members are not considered copy-assignable.
The destructor is always automatically supplied if possible, based on the members and the base classes.
In C++11, A move constructor with an argument T && is supplied unless the class has any of the following: a user-defined copy constructor, copy-assignment operator, move-assignment operator, or destructor. If the move constructor cannot be implemented because not all bases or members are move-constructible, the supplied move constructor will be defined as deleted.
Similarly, in C++11, a move-assignment operator T &T::operator=(T &&) is supplied under the same conditions.
Comparison operator such as bool operator==(const T &) const are never automatically generated by the compiler, even if all base classes and members are comparable.
In order to suppress the automatically generated copy constructor and copy-assignment operator, it is customary in C++03 and earlier to declare them as private members, but do not define them:
class T {
T(const T &); // not implemented
T &operator=(const T &); // not implemented
public:
...
};
This will result in a compile-time error if code which has not private access tries to use this members, or a link-time error for code that has access. In C++11 and later, the delete should be used because it results in a better diagnostic:
class T {
T(const T &) = delete;
T &operator=(const T &) = delete;
public:
...
};
C++11 supports initialization of members as part of the class declaration, like this:
class T {
int a = 1;
public:
explicit T(int);
}
Here, the user-defined constructor prevents generation of the default constructor with the initialization operations. Generation of the default constructor can be requested using the default keyword.
class T {
int a = 1;
public:
explicit T(int);
T() = default;
}
The rules are fairly simple (as far as things related to C++ are considered), and after writing them down, I will probably never have to look at this note again.
2013-11-02: published