Some C++ constructors are special, the default constructor is one of them.

This article is part of a series on the history of regular data type in C++.

Default constructor

I’ve already mentioned that the constructor has more facilities that the destructor, such that you can have function parameters, hence you can have multiple constructors that differ in the parameters they take.

The constructor without any parameters is called the default constructor.

1
2
3
4
5
6
7
8
9
10
11
struct foo {
  foo() {
    // default constructor
  }

  foo(int i, int j) {
    // some other constructor
  }

  // ...
};

The default constructor is used when you “just need an instance”:

1
2
3
int main() {
  foo x; // default constructor is used to initialize x
};

Kinds of default constructor

When you have an int, there are two ways to construct one out of thin air. Uninitialized:

1
2
3
int main() {
  int i; // some int, uninitialized
};

or initialized:

1
2
3
4
5
int main() {
  int i{}; // initialized to 0
  // equivalent to:
  int j = 0;
};

When we have a struct containing a pointer that is deallocated in the destructor, in the constructor we have to do enough so that we don’t try to deallocate using an uninitialized pointer, usually at least we have to initialize the pointer to nullptr in the default constructor:

1
2
3
4
5
6
7
8
struct foo {
  bar * p;

  foo() : p{nullptr} {
  }

  // ...
};

But when we have a struct containing an int:

1
2
3
4
5
6
7
struct buzz {
  int i;

  buzz() {
    // should we initialize i or not?
  }
};

Should we initialize the int member variable? Can we do both? Unfortunately the language does not have syntax for two kinds of default constructors, so the answer is “depends”. More often than not you’ll want to initialize, trading a bit of efficiency for safety in general.

This is annoying when you just need a resizable buffer to read some data from a file, you reach for a std::vector<usigned char>: when resized to the desired size, it will also initialize values to 0, even if they will be overwritten later when content is read from the file.