Constructor Rules in C++
(Acknowledgements to https://www.modernescpp.com/index.php/c-core-guidelines-constructors/, by Rainer Grimm)
These are the thirteen most fundamental rules for object construction:
- Define a constructor if a class has an invariant, that is a member variable existing throughout the object's life cycle, or state.
- A constructor should create a fully initialized object
- If a constructor cannot construct a valid object, throw an exception
- Ensure that a value type class has a default constructor. Many constructors of STL containers rely assume your type has a default constructor.
- Prefer default constructors to be simple and non-throwing (append
noexept
) - Don't define a default constructor that only initializes data members; use member initializers instead
- By default, declare single-argument constructors
explicit
. This is a crucial rule. Single-argument constructors are often called conversion constructors. If you do not make them explicit, an implicit conversion may happen. - Define and initialize member variables in the order of member declaration. If you initialize them in a different order, you may get unexpected results.
- Prefer in-class initializers to member initializers in constructors for constant initializers
- Prefer initialization to assignment in constructors
- Use a factory function if you need
virtual behavior
during initialization. Calling a virtual function from a constructor will not work as expected. For protection reasons, the virtual call mechanism is disabled in the constructor because the creation of the derived class hasn't happened. - Use delegating constructors to represent common actions for all constructors of a class
- Use inheriting constructors to import constructors into a derived class that does not need further explicit initialization. If you can reuse constructors of the base class in the derived class, do it. You violate the DRY (Don't Repeat Yourself) principle if you don't do it.