C++ Constructor Patterns

1 minute read

Default

Setting a default constructor allows instantiation of an object using the default values of the class member variables.

class Wheel {
public:
  Wheel(void) = default;

  double radius = 1.0;
  double mass = 0.0;
};

int main() {
  Wheel myWheel {};
  std::cout << myWheel.radius << std::endl; // 1.0 
  std::cout << myWheel.mass << std::endl;   // 0.0
}

Run on cpp.sh

Note: the above code also runs when no constructor is defined; this isn’t always the case and depends on data members, so it is best to use default when that is the desired behaviour

Private/Delete

Sometimes, we want a class to not have a constructor. Maybe we want it as a base class or maybe we only want it for it’s static members.

class WheelBase {
public:
  WheelBase(void) = delete;

  double radius = 1.0;
  double mass = 0.0;
};

class PanelBase {
public:
  double area = 1.0;
private:
    PanelBase(void);
};

int main() {
  WheelBase myWheel; // Compile error
  PanelBase myPanel; // Compile error
}

Run on cpp.sh

The private constructor is also an important part of implementing the singleton pattern.

Explicit

The explicit specifier prevents instantiation of a class using a conversion, and is only really used for constructors with a single parameter.

class ConvertingPanel {
public:
  ConvertingPanel(double areaIn) : area(areaIn) {}
  double area = 1.0;
};

class ExplicitPanel {
public:
  explicit ExplicitPanel(double areaIn) : area(areaIn) {}
  double area = 1.0;
};

int main() {
  ImplicitPanel panel2 = 0.0; // OK
  ExplicitPanel panel1 = 1.0; // Compile error
}

Run on cpp.sh

Converting constructors are generally regarded as bad practice since their behaviour is not always intuitive.