How to have both the default and custom constructors?

Summary

To have both a default and custom constructor in C++, you need to understand how constructor initialization lists and aggregate initialization work. The key takeaway is that when you define a custom constructor, the compiler no longer generates a default constructor for you, which is used for aggregate initialization.

Root Cause

The root cause of the issue is that when a custom constructor is defined, the compiler does not generate a default constructor, which is necessary for aggregate initialization. The reasons for this include:

  • The compiler only generates a default constructor if no user-declared constructors are present.
  • Custom constructors do not allow for aggregate initialization by default.

Why This Happens in Real Systems

This happens in real systems because of the way C++ handles constructor generation and aggregate initialization. The main points to consider are:

  • Aggregate initialization requires a default constructor or no user-declared constructors.
  • Custom constructors can prevent aggregate initialization if not implemented correctly.

Real-World Impact

The real-world impact of this issue includes:

  • Inability to use aggregate initialization with custom constructors.
  • Increased code complexity due to the need for custom constructors.
  • Potential for errors if not handled correctly.

Example or Code

struct foo_t {
    int foo;
    double bar;
    foo_t() = default; // Allow aggregate initialization
    foo_t(int both) : foo(both), bar(both) {}
};

foo_t foo0(1);
foo_t foo1{.bar = 1};
foo_t foo2{.foo = 2, .bar = 3.0};

How Senior Engineers Fix It

Senior engineers fix this issue by:

  • Understanding how constructor initialization lists and aggregate initialization work.
  • Using the default constructor to allow for aggregate initialization.
  • Implementing custom constructors correctly to avoid preventing aggregate initialization.
  • Using designated initializers to specify the members being initialized.

Why Juniors Miss It

Juniors may miss this issue because they:

  • Lack understanding of constructor initialization lists and aggregate initialization.
  • Do not realize the impact of custom constructors on aggregate initialization.
  • Fail to use the default constructor to allow for aggregate initialization.
  • Do not test their code thoroughly to catch errors related to aggregate initialization.