If you dont write a constructor for a class object, c# writes one for you.

A class contains constructors that are invoked to create objects from the class blueprint. Constructor declarations look like method declarations—except that they use the name of the class and have no return type. For example, Bicycle has one constructor:

Show

public Bicycle(int startCadence, int startSpeed, int startGear) {
    gear = startGear;
    cadence = startCadence;
    speed = startSpeed;
}

To create a new Bicycle object called myBike, a constructor is called by the new operator:

Bicycle myBike = new Bicycle(30, 0, 8);

new Bicycle(30, 0, 8) creates space in memory for the object and initializes its fields.

Although Bicycle only has one constructor, it could have others, including a no-argument constructor:

public Bicycle() {
    gear = 1;
    cadence = 10;
    speed = 0;
}

Bicycle yourBike = new Bicycle(); invokes the no-argument constructor to create a new Bicycle object called

Bicycle myBike = new Bicycle(30, 0, 8);
1.

Both constructors could have been declared in Bicycle because they have different argument lists. As with methods, the Java platform differentiates constructors on the basis of the number of arguments in the list and their types. You cannot write two constructors that have the same number and type of arguments for the same class, because the platform would not be able to tell them apart. Doing so causes a compile-time error.

You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of

Bicycle myBike = new Bicycle(30, 0, 8);
3, which does have a no-argument constructor.

You can use a superclass constructor yourself. The

Bicycle myBike = new Bicycle(30, 0, 8);
4 class at the beginning of this lesson did just that. This will be discussed later, in the lesson on interfaces and inheritance.

You can use access modifiers in a constructor's declaration to control which other classes can call the constructor.

Constructors are like “init functions”. They turn a pile of arbitrary bits into a living object. Minimally they initialize internally used fields. They may also allocate resources (memory, files, semaphores, sockets, etc).

“ctor” is a typical abbreviation for constructor.

Is there any difference between class Fred { public: Fred(); // ... }; int main() { Fred a[10]; // Calls the default constructor 10 times Fred* p = new Fred[10]; // Calls the default constructor 10 times // ... } 0 and class Fred { public: Fred(); // ... }; int main() { Fred a[10]; // Calls the default constructor 10 times Fred* p = new Fred[10]; // Calls the default constructor 10 times // ... } 1?

A big difference!

Suppose that

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
2 is the name of some class. Then function
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
3 declares a local
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
2 object called
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5:

void f()
{
  List x;     // Local object named x (of class List)
  // ...
}

But function

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
6 declares a function called
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
7 that returns a
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
2:

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}

Can one constructor of a class call another constructor of the same class to initialize the class Fred { public: Fred(); // ... }; int main() { Fred a[10]; // Calls the default constructor 10 times Fred* p = new Fred[10]; // Calls the default constructor 10 times // ... } 9 object?

The answer below applies to Classic (pre-11) C++. This question covers the C++11 feature of constructors that call same-type constructors.

Nope.

Let’s work an example. Suppose you want your constructor

class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
0 to call another constructor of the same class, say
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
1, in order that
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
1 would help initialize the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object. Unfortunately there’s no way to do this in Classic C++.

Some people do it anyway. Unfortunately it doesn’t do what they want. For example, the line

class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
4 does not call
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
1 on the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object. Instead it calls
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
1 to initialize a temporary, local object (not
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9), then it immediately destructs that temporary when control flows over the
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
9.

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}

You can sometimes combine two constructors via a default parameter:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};

If that doesn’t work, e.g., if there isn’t an appropriate default parameter that combines the two constructors, sometimes you can share their common code in a private

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
0 member function:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}

BTW do NOT try to achieve this via placement new. Some people think they can say

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
1 within the body of
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
0. However that is bad, bad, bad. Please don’t write me and tell me that it seems to work on your particular version of your particular compiler; it’s bad. Constructors do a bunch of little magical things behind the scenes, but that bad technique steps on those partially constructed bits. Just say no.

Is the default constructor for #include int main() { std::vector a(10, Fred(5,7)); // The 10 Fred objects in std::vector a will be initialized with Fred(5,7) // ... } 3 always #include int main() { std::vector a(10, Fred(5,7)); // The 10 Fred objects in std::vector a will be initialized with Fred(5,7) // ... } 4?

No.

A “default constructor” is a constructor that can be called with no arguments. One example of this is a constructor that takes no parameters:

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};

Another example of a “default constructor” is one that can take arguments, provided they are given default values:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};

Which constructor gets called when I create an array of #include int main() { std::vector a(10, Fred(5,7)); // The 10 Fred objects in std::vector a will be initialized with Fred(5,7) // ... } 3 objects?

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3’s default constructor (except as discussed below).

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}

If your class doesn’t have a default constructor, you’ll get a compile-time error when you attempt to create an array using the above simple syntax:

class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}

However, even if your class already has a default constructor, you should try to use

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
7 rather than an array (arrays are evil).
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
8 lets you decide to use any constructor, not just the default constructor:

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}

Even though you ought to use a

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
8 rather than an array, there are times when an array might be the right thing to do, and for those, you might need the “explicit initialization of arrays” syntax. Here’s how:

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
0

Of course you don’t have to do

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
00 for every entry — you can put in any numbers you want, even parameters or other variables.

Finally, you can use placement-new to manually initialize the elements of the array. Warning: it’s ugly: the raw array can’t be of type

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3, so you’ll need a bunch of pointer-casts to do things like compute array index operations. Warning: it’s compiler- and hardware-dependent: you’ll need to make sure the storage is aligned with an alignment that is at least as strict as is required for objects of class
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3. Warning: it’s tedious to make it exception-safe: you’ll need to manually destruct the elements, including in the case when an exception is thrown part-way through the loop that calls the constructors. But if you really want to do it anyway, read up on placement-new. (BTW placement-new is the magic that is used inside of
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
8. The complexity of getting everything right is yet another reason to use
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
8.)

By the way, did I ever mention that arrays are evil? Or did I mention that you ought to use a

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
8 unless there is a compelling reason to use an array?

Should my constructors use “initialization lists” or “assignment”?

Initialization lists. In fact, constructors should initialize as a rule all member objects in the initialization list. One exception is discussed further down.

Watch this space for discussion of Non Static Data Member Initialization in C++11

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
1

Consider the following constructor that initializes member object

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
06 using an initialization list:
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
07whatever
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
08. The most common benefit of doing this is improved performance. For example, if the expression whatever is the same type as member variable
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
06, the result of the whatever expression is constructed directly inside
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
06 — the compiler does not make a separate copy of the object. Even if the types are not the same, the compiler is usually able to do a better job with initialization lists than with assignments.

The other (inefficient) way to build constructors is via assignment, such as:

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
11whatever
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
12. In this case the expression whatever causes a separate, temporary object to be created, and this temporary object is passed into the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
06 object’s assignment operator. Then that temporary object is destructed at the
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
9. That’s inefficient.

As if that wasn’t bad enough, there’s another source of inefficiency when using assignment in a constructor: the member object will get fully constructed by its default constructor, and this might, for example, allocate some default amount of memory or open some default file. All this work could be for naught if the whatever expression and/or assignment operator causes the object to close that file and/or release that memory (e.g., if the default constructor didn’t allocate a large enough pool of memory or if it opened the wrong file).

Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.

Note: There is no performance difference if the type of

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
06 is some built-in/intrinsic type, such as
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
16 or
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
17 or
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
18. But even in these cases, my personal preference is to set those data members in the initialization list rather than via assignment for consistency. Another symmetry argument in favor of using initialization lists even for built-in/intrinsic types: non-static
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
19 and non-static reference data members can’t be assigned a value in the constructor, so for symmetry it makes sense to initialize everything in the initialization list.

Now for the exceptions. Every rule has exceptions (hmmm; does “every rule has exceptions” have exceptions? reminds me of Gödel’s Incompleteness Theorems), and there are a couple of exceptions to the “use initialization lists” rule. Bottom line is to use common sense: if it’s cheaper, better, faster, etc. to not use them, then by all means, don’t use them. This might happen when your class has two constructors that need to initialize the

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object’s data members in different orders. Or it might happen when two data members are self-referential. Or when a data-member needs a reference to the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object, and you want to avoid a compiler warning about using the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 keyword prior to the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
23 that begins the constructor’s body (when your particular compiler happens to issue that particular warning). Or when you need to do an
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
24…
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
25 test on a variable (parameter, global, etc.) prior to using that variable to initialize one of your
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 members. This list is not exhaustive; please don’t write me asking me to add another “Or when…”. The point is simply this: use common sense.

How should initializers be ordered in a constructor’s initialization list?

Immediate base classes (left to right), then member objects (top to bottom).

In other words, the order of the initialization list should mimic the order in which initializations will take place. This guideline discourages a particularly subtle class of order dependency errors by giving an obvious, visual clue. For example, the following contains a hideous error.

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
2

The output of this program follows.

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
3

Note that

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
27 is used (
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
28) before it is initialized (
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
29). If instead the programmer had read and abided by the guideline in this FAQ, the error would be more obvious: the initialization list of
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
30 would have read
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
31, visually indicating that
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
27 was being used before being initialized.

Not all compilers issue diagnostic messages for these cases. You have been warned.

Is it moral for one member object to be initialized using another member object in the initializer expression?

Yes, but use care and do that only when it adds value.

In a constructor’s initialization list, it is easiest and safest to avoid using one member object from

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object in the initialization expression of a subsequent initializer for
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object. This guideline prevents subtle order-dependency errors if someone reorganizes the layout of member objects within the class.

Because of this guideline, the constructor that follows uses

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
35 rather than
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
36, even though they are otherwise equivalent. The
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
37 prefix avoids an unnecessary and avoidable order dependency.

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
4

An unnecessary order dependency on the class layout of

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
38 and
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
39 would have been introduced if the constructor’s initialization of
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
39 had used
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
36 rather than
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
35. However using
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
38 within a constructor body (
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
44) is okay. No order dependency is introduced since the entire initialization list is guaranteed to finish before the constructor body begins executing.

What if one member object has to be initialized using another member object?

Comment the declaration of the effected data members with

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
45.

If a constructor initializes a member object of

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object using another member object of
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object, rearranging the data members of the class could break the constructor. This important maintenance constraint should be documented in the class body.

For example, in the constructor below, the initializer for

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
39 uses
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
38 to avoid a redundant call to
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
50, which introduces an order dependency in the class body.

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
5

Note that the

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
45 comment is listed with the effected data members in the class body, not with the constructor initialization list where the order dependency was actually created. That is because the order of member objects in the class body is critical; the order of initializers in the constructor initialization list is irrelevant.

Should you use the class Fred { public: Fred(); // ... }; int main() { Fred a[10]; // Calls the default constructor 10 times Fred* p = new Fred[10]; // Calls the default constructor 10 times // ... } 9 pointer in the constructor?

Some people feel you should not use the

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 pointer in a constructor because the object is not fully formed yet. However you can use
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 in the constructor (in the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
23body
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
56 and even in the initialization list) if you are careful.

Here is something that always works: the

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
23body
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
56 of a constructor (or a function called from the constructor) can reliably access the data members declared in a base class and/or the data members declared in the constructor’s own class. This is because all those data members are guaranteed to have been fully constructed by the time the constructor’s
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
23body
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
56 starts executing.

Here is something that never works: the

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
23body
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
56 of a constructor (or a function called from the constructor) cannot get down to a derived class by calling a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
63 member function that is overridden in the derived class. If your goal was to get to the overridden function in the derived class, you won’t get what you want. Note that you won’t get to the override in the derived class independent of how you call the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
63 member function: explicitly using the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 pointer (e.g.,
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
66), implicitly using the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 pointer (e.g.,
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
68), or even calling some other function that calls the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
63 member function on your
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object. The bottom line is this: even if the caller is constructing an object of a derived class, during the constructor of the base class, your object is not yet of that derived class. You have been warned.

Here is something that sometimes works: if you pass any of the data members in

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object to another data member’s initializer, you must make sure that the other data member has already been initialized. The good news is that you can determine whether the other data member has (or has not) been initialized using some straightforward language rules that are independent of the particular compiler you’re using. The bad news is that you have to know those language rules (e.g., base class sub-objects are initialized first (look up the order if you have multiple and/or
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
63 inheritance!), then data members defined in the class are initialized in the order in which they appear in the class declaration). If you don’t know these rules, then don’t pass any data member from the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object (regardless of whether or not you explicitly use the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 keyword) to any other data member’s initializer! And if you do know the rules, please be careful.

What is the “Named Constructor Idiom”?

A technique that provides more intuitive and/or safer construction operations for users of your class.

The problem is that constructors always have the same name as the class. Therefore the only way to differentiate between the various constructors of a class is by the parameter list. But if there are lots of constructors, the differences between them become somewhat subtle and error prone.

With the Named Constructor Idiom, you declare all the class’s constructors in the

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
75 or
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
76 sections, and you provide
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
77
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 methods that return an object. These
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 methods are the so-called “Named Constructors.” In general there is one such
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 method for each different way to construct an object.

For example, suppose we are building a

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
81 class that represents a position on the X-Y plane. Turns out there are two common ways to specify a 2-space coordinate: rectangular coordinates (X+Y), polar coordinates (Radius+Angle). (Don’t worry if you can’t remember these; the point isn’t the particulars of coordinate systems; the point is that there are several ways to create a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
81 object.) Unfortunately the parameters for these two coordinate systems are the same: two
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
18s. This would create an ambiguity error in the overloaded constructors:

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
6

One way to solve this ambiguity is to use the Named Constructor Idiom:

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
7

Now the users of

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
81 have a clear and unambiguous syntax for creating
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
81s in either coordinate system:

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
8

Make sure your constructors are in the

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
76 section if you expect
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
81 to have derived classes.

The Named Constructor Idiom can also be used to make sure your objects are always created via

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
88.

Note that the Named Constructor Idiom, at least as implemented above, is just as fast as directly calling a constructor — modern compilers will not make any extra copies of your object.

Does return-by-value mean extra copies and extra overhead?

Not necessarily.

All(?) commercial-grade compilers optimize away the extra copy, at least in cases as illustrated in the previous FAQ.

To keep the example clean, let’s strip things down to the bare essentials. Suppose function

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89 calls
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90 (“rbv” stands for “return by value”) which returns a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object by value:

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
9

Now the question is, How many

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 objects will there be? Will
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90 create a temporary
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object that gets copy-constructed into
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5? How many temporaries? Said another way, does return-by-value necessarily degrade performance?

The point of this FAQ is that the answer is No, commercial-grade C++ compilers implement return-by-value in a way that lets them eliminate the overhead, at least in simple cases like those shown in the previous FAQ. In particular, all(?) commercial-grade C++ compilers will optimize this case:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
0

Certainly the compiler is allowed to create a temporary, local

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object, then copy-construct that temporary into variable
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 within
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89, then destruct the temporary. But all(?) commercial-grade C++ compilers won’t do that: the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
99 statement will directly construct
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 itself. Not a copy of
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5, not a pointer to
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5, not a reference to
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5, but
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 itself.

You can stop here if you don’t want to genuinely understand the previous paragraph, but if you want to know the secret sauce (so you can, for example, reliably predict when the compiler can and cannot provide that optimization for you), the key is to know that compilers usually implement return-by-value using pass-by-pointer. When

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89 calls
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90, the compiler secretly passes a pointer to the location where
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90 is supposed to construct the “returned” object. It might look something like this (it’s shown as a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
08 rather than a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
09 since the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object has not yet been constructed):

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
1

So the first ingredient in the secret sauce is that the compiler (usually) transforms return-by-value into pass-by-pointer. This means that commercial-grade compilers don’t bother creating a temporary: they directly construct the returned object in the location pointed to by

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
11.

The second ingredient in the secret sauce is that compilers typically implement constructors using a similar technique. This is compiler-dependent and somewhat idealized (I’m intentionally ignoring how to handle

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
88 and overloading), but compilers typically implement
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
13 using something like this:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
2

Putting these together, the compiler might implement the

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
99 statement in
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90 by simply passing
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
11 as the constructor’s
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 pointer:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
3

So

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89 passes
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
19 to
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90, and
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90 in turn passes
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
19 to the constructor (as the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 pointer). That means constructor directly constructs
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5.

In the early 90s I did a seminar for IBM’s compiler group in Toronto, and one of their engineers told me that they found this return-by-value optimization to be so fast that you get it even if you don’t compile with optimization turned on. Because the return-by-value optimization causes the compiler to generate less code, it actually improves compile-times in addition to making your generated code smaller and faster. The point is that the return-by-value optimization is almost universally implemented, at least in code cases like those shown above.

Final thought: this discussion was limited to whether there will be any extra copies of the returned object in a return-by-value call. Don’t confuse that with other things that could happen in

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89. For example, if you changed
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89 from
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
27 to
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
28
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
29 (note the
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
9 after the declaration), the compiler is required to use
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91’s assignment operator, and unless the compiler can prove that
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91’s default constructor followed by assignment operator is exactly the same as its copy constructor, the compiler is required by the language to put the returned object into an unnamed temporary within
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89, use the assignment operator to copy the temporary into
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5, then destruct the temporary. The return-by-value optimization still plays its part since there will be only one temporary, but by changing
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
27 to
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
28
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
29, you have prevented the compiler from eliminating that last temporary.

What about returning a local variable by value? Does the local exist as a separate object, or does it get optimized away?

When your code returns a local variable by value, your compiler might optimize away the local variable completely - zero space-cost and zero time-cost - the local variable never actually exists as a distinct object from the caller’s target variable (see below for specifics about exactly what this means). Other compilers do not optimize it away.

These are some(!) of the compilers that optimize away the local variable completely:

  • GNU C++ (g++) since at least version 3.3.3
  • (Others need to be added; need more info)

These are some(!) of the compilers that do not optimize away the local variable:

  • Microsoft Visual C++.NET 2003
  • (Others need to be added; need more info)

Here is an example showing what we mean in this FAQ:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
4

The question addressed in this FAQ is this: How many

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 objects actually get created in the runtime system? Conceptually there could be as many as three distinct objects: the temporary created by
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
39, variable
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 (in
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90), and variable
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 (in
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89). However as we saw earlier most compilers merge
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
39 and variable
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 into the same object, reducing the total number of objects from 3 to 2. But this FAQ pushes it one step further: does
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 (in
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90) show up as a distinct, runtime object from
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 (in
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89)?

Some compilers, including but not limited to those listed above, completely optimize away local variable

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40. In those compilers, there is only one
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object in the above code:
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89’s variable
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 is exactly identically the same object as
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90’s variable
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40.

They do this the same way as described earlier: the return-by-value in function

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90 is implemented as pass-by-pointer, where the pointer points to the location where the returned object is to be initialized.

So instead of constructing

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 as a local object, these compilers simply construct
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
58, and everytime they see variable
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 used in the original source code, they substitute
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
58 instead. Then the line
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
61 becomes simply
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
62 since the returned object has already been constructed in the location designated by the caller.

Here is the resulting (pseudo)code:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
5

Caveat: this optimization can be applied only when all a function’s

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
99 statements return the same local variable. If one
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
99 statement in
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
90 returned local variable
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 but another returned something else, such as a global or a temporary, the compiler could not alias the local variable into the caller’s destination,
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5. Verifying that all the function’s return statements return the same local variable requires extra work on the part of the compiler writers, which is usually why some compilers fail to implement that return-local-by-value optimization.

Final thought: this discussion was limited to whether there will be any extra copies of the returned object in a return-by-value call. Don’t confuse that with other things that could happen in

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89. For example, if you changed
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89 from
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
27 to
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
28
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
29 (note the
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
9 after the declaration), the compiler is required to use
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91’s assignment operator, and unless the compiler can prove that
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91’s default constructor followed by assignment operator is exactly the same as its copy constructor, the compiler is required by the language to put the returned object into an unnamed temporary within
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
89, use the assignment operator to copy the temporary into
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5, then destruct the temporary. The return-by-value optimization still plays its part since there will be only one temporary, but by changing
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
27 to
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
28
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
29, you have prevented the compiler from eliminating that last temporary.

Why can’t I initialize my void g() { List x(); // Function named x (that returns a List) // ... } 78 member data in my constructor’s initialization list?

Because you must explicitly define your class’s

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 data members.

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
83:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
6

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
84 (or
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
85 or whatever):

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
7

Note: in some cases, the definition of

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
86 might not contain the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
87 initializer part. For details, see here and here.

Why are classes with void g() { List x(); // Function named x (that returns a List) // ... } 78 data members getting linker errors?

Because

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 data members must be explicitly defined in exactly one compilation unit. If you didn’t do this, you’ll probably get an
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
90 linker error. For example:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
8

The linker will holler at you (

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
91) unless you define (as opposed to merely declare)
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
86 in (exactly) one of your source files:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
9

The usual place to define

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 data members of
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
94
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 is file
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
84 (or
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
85 or whatever source file extension you use).

Note: in some cases, you can add

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
87 initializer
class Fred {
public:
  Fred(int i, int j);      // Assume there is no default constructor
  // ...
};

int main()
{
  Fred a[10];              // ERROR: Fred doesn't have a default constructor
  Fred* p = new Fred[10];  // ERROR: Fred doesn't have a default constructor
  // ...
}
9 to the declaration of class-scope
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 declarations, however if you ever use the data member, you still need to explicitly define it in exactly one compilation unit. In this case you don’t include an
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
87 initializer in the definition. A separate FAQ covers this topic.

Can I add class Foo { public: Foo(char x); Foo(char x, int y); // ... }; Foo::Foo(char x) { // ... Foo(x, 0); // Does NOT help initialize the this object!! // ... } 87 initializerclass Fred { public: Fred(int i, int j); // Assume there is no default constructor // ... }; int main() { Fred a[10]; // ERROR: Fred doesn't have a default constructor Fred* p = new Fred[10]; // ERROR: Fred doesn't have a default constructor // ... } 9 to the declaration of a class-scope void g() { List x(); // Function named x (that returns a List) // ... } 78 void g() { List x(); // Function named x (that returns a List) // ... } 19 data member?

Yes, though with some important caveats.

Before going through the caveats, here is a simple example that is allowed:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
0

And, just like other

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 data members, it must be defined in exactly one compilation unit, though this time without the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
87 initializer part:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
1

The caveats are that you may do this only with integral or enumeration types, and that the initializer expression must be an expression that can be evaluated at compile-time: it must only contain other constants, possibly combined with built-in operators. For example,

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
08 is a compile-time constant expression, as is
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
09 provided
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
10 and
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
11 are compile-time constants. After the declaration above,
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
12 is also a compile-time constant: it can be used in other compile-time constant expressions.

If you ever take the address of

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
12, such as passing it by reference or explicitly saying
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
14, the compiler will make sure it has a unique address. If not,
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
12 won’t even take up space in your process’s static data area.

What’s the “void g() { List x(); // Function named x (that returns a List) // ... } 78 initialization order ‘fiasco’ (problem)”?

A subtle way to crash your program.

The

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 initialization order problem is a very subtle and commonly misunderstood aspect of C++. Unfortunately it’s very hard to detect — the errors often occur before
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
18 begins.

In short, suppose you have two

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 objects
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 and
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 which exist in separate source files, say
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
22 and
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
23. Suppose further that the initialization for the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 object (typically the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 object’s constructor) calls some method on the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 object.

That’s it. It’s that simple.

The tough part is that you have a 50%-50% chance of corrupting the program. If the compilation unit for

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
22 happens to get initialized first, all is well. But if the compilation unit for
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
23 get initialized first, then
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40’s initialization will get run before
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5’s initialization, and you’re toast. E.g.,
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40’s constructor could call a method on the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 object, yet the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 object hasn’t yet been constructed.

For how to address the problem, see the next FAQ.

Note: The static initialization order problem can also, in some cases, apply to built-in/intrinsic types.

How do I prevent the “void g() { List x(); // Function named x (that returns a List) // ... } 78 initialization order problem”?

To prevent the static initialization order problem, use the Construct On First Use Idiom, described below.

The basic idea of the Construct On First Use Idiom is to wrap your

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 object inside a function. For example, suppose you have two classes,
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 and
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
37. There is a namespace-scope / global
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object called
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5, and a namespace-scope / global
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
37 object called
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40.
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
37’s constructor invokes the
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
43 method on the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 object. The file
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
22 defines the
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 object:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
2

The file

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
23 defines the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 object:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
3

For completeness the

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
37 constructor might look something like this:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
4

You would have a

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 initialization disaster if
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 got constructed before
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5. As written above, this disaster would occur roughly 50% of the time, since the two objects are declared in different source files and those source files give no hints to the compiler or linker as to the order of static initialization.

There are many solutions to this problem, but a very simple and completely portable solution is the Construct On First Use Idiom: replace the namespace-scope / global

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 with a namespace-scope / global function
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
7 that returns the
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object by reference.

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
5

Since

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 local objects are constructed the first time control flows over their declaration (only), the above
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
58 statement will only happen once: the first time
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
7 is called. Every subsequent call will return the same
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object (the one pointed to by
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61). Then all you do is change your usages of
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 to
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
7:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
6

This is called the Construct On First Use Idiom because it does just that: the (logically namespace-scope / global)

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object is constructed on its first use.

The downside of this approach is that the

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object is never destructed. If the
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object has a destructor with important side effects, there is another technique that answers this concern; but it needs to be used with care since it creates the possibility of another (equally nasty) problem.

Note: The static initialization order problem can also, in some cases, apply to built-in/intrinsic types.

Why doesn’t the Construct On First Use Idiom use a void g() { List x(); // Function named x (that returns a List) // ... } 78 object instead of a void g() { List x(); // Function named x (that returns a List) // ... } 78 pointer?

Short answer: it’s possible to use a static object rather than a static pointer, but doing so opens up another (equally subtle, equally nasty) problem.

Long answer: sometimes people worry about the fact that the previous solution “leaks.” In many cases, this is not a problem, but it is a problem in some cases. Note: even though the object pointed to by

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 in the previous FAQ is never deleted, the memory doesn’t actually “leak” when the program exits since the operating system automatically reclaims all the memory in a program’s heap when that program exits. In other words, the only time you’d need to worry about this is when the destructor for the
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object performs some important action (such as writing something to a file) that must occur sometime while the program is exiting.

In those cases where the construct-on-first-use object (the

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3, in this case) needs to eventually get destructed, you might consider changing function
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
7 as follows:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
7

However there is (or rather, may be) a rather subtle problem with this change. To understand this potential problem, let’s remember why we’re doing all this in the first place: we need to make 100% sure our static object (a) gets constructed prior to its first use and (b) doesn’t get destructed until after its last use. Obviously it would be a disaster if any static object got used either before construction or after destruction. The message here is that you need to worry about two situations (static initialization and static deinitialization), not just one.

By changing the declaration from

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
73 to
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
74, we still correctly handle the initialization situation but we no longer handle the deinitialization situation. For example, if there are 3 static objects, say
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
10,
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
11 and
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
77, that use
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 during their destructors, the only way to avoid a static deinitialization disaster is if
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 is destructed after all three.

The point is simple: if there are any other static objects whose destructors might use

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 after
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 is destructed, bang, you’re dead. If the constructors of
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
10,
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
11 and
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
77 use
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61, you should normally be okay since the runtime system will, during static deinitialization, destruct
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 after the last of those three objects is destructed. However if
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
10 and/or
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
11 and/or
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
77 fail to use
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 in their constructors and/or if any code anywhere gets the address of
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
61 and hands it to some other static object, all bets are off and you have to be very, very careful.

There is a third approach that handles both the static initialization and static deinitialization situations, but it has other non-trivial costs.

What is a technique to guarantee both void g() { List x(); // Function named x (that returns a List) // ... } 78 initialization and void g() { List x(); // Function named x (that returns a List) // ... } 78 deinitialization?

Short answer: use the Nifty Counter Idiom (but make sure you understand the non-trivial tradeoffs!).

Motivation:

  • The Construct On First Use Idiom uses a pointer and intentionally leaks the object. That is often innocuous, since the operating system will typically clean up a process’s memory when the process terminates. However if the object has a non-trivial destructor with important side effects, such as writing to a file or some other non-volatile action, then you need more.
  • That’s where the second version of the Construct On First Use Idiom came in: it doesn’t leak the object, but it does not control the order of static deinitialization, so it is (very!) unsafe to use the object during static deinitialization, that is, from a destructor of another statically declared object.
  • If you need to control the order of both static initialization and static deinitialization, meaning if you wish to access a statically allocated object from both constructors and destructors of other static objects, then keep reading.
  • Otherwise run away.

TODO: WRITE THIS UP

TODO: WRITE UP TRADEOFFS — now that you know how to use the Nifty Counter Idiom, be sure you understand both when and (especially!) when not to use it! One size does not fit all.

How do I prevent the “void g() { List x(); // Function named x (that returns a List) // ... } 78 initialization order problem” for my void g() { List x(); // Function named x (that returns a List) // ... } 78 data members?

Use the Construct Members On First Use Idiom, which is basically the same as the regular Construct On First Use Idiom, or perhaps one of its variants, but it uses a

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 member function instead of a namespace-scope / global function.

Suppose you have a class

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
97 that has a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78
#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
8

Naturally this

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 member is initialized separately:

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
9

Naturally also the

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object will be used in one or more of
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
97’s methods:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
0

But now the “disaster scenario” is if someone somewhere somehow calls this method before the

#include 

int main()
{
  std::vector a(10, Fred(5,7));  // The 10 Fred objects in std::vector a will be initialized with Fred(5,7)
  // ...
}
3 object gets constructed. For example, if someone else creates a static
class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
97 object and invokes its
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
05 method during
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 initialization, then you’re at the mercy of the compiler as to whether the compiler will construct
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
07 before or after the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
05 is called. (Note that the ANSI/ISO C++ committee is working on this problem, but compilers aren’t yet generally available that handle these changes; watch this space for an update in the future.)

In any event, it’s always portable and safe to change the

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
07
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 data member into a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 member function:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
1

Naturally this

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 member is initialized separately:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
2

Then you simply change any usages of

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
06 to
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
7:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
3

If you’re super performance sensitive and you’re concerned about the overhead of an extra function call on each invocation of

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
15 you can set up a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
17 instead. As you recall,
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
78 local are only initialized once (the first time control flows over their declaration), so this will call
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
19 only once: the first time
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
15 is called:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
4

Note: The static initialization order problem can also, in some cases, apply to built-in/intrinsic types.

Do I need to worry about the “void g() { List x(); // Function named x (that returns a List) // ... } 78 initialization order problem” for variables of built-in/intrinsic types?

Yes.

If you initialize your built-in/intrinsic type using a function call, the static initialization order problem is able to kill you just as bad as with user-defined/class types. For example, the following code shows the failure:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
5

The output of this little program will show that it uses

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 before initializing it. The solution, as before, is the Construct On First Use Idiom:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
6

Of course you might be able to simplify this by moving the initialization code for

class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 and
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 into their respective functions:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
7

And, if you can get rid of the print statements you can further simplify these to something really simple:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
8

Furthermore, since

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
40 is initialized using a constant expression, it no longer needs its wrapper function — it can be a simple variable again.

How can I handle a constructor that fails?

Throw an exception. For details, see here.

What is the “Named Parameter Idiom”?

It’s a fairly useful way to exploit method chaining.

The fundamental problem solved by the Named Parameter Idiom is that C++ only supports positional parameters. For example, a caller of a function isn’t allowed to say, “Here’s the value for formal parameter

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
26, and this other thing is the value for formal parameter
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
27.” All you can do in C++ (and C and Java) is say, “Here’s the first parameter, here’s the second parameter, etc.” The alternative, called named parameters and implemented in the language Ada, is especially useful if a function takes a large number of mostly default-able parameters.

Over the years people have cooked up lots of workarounds for the lack of named parameters in C and C++. One of these involves burying the parameter values in a string parameter then parsing this string at run-time. This is what’s done in the second parameter of

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
28, for example. Another workaround is to combine all the boolean parameters in a bit-map, then the caller or’s a bunch of bit-shifted constants together to produce the actual parameter. This is what’s done in the second parameter of
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
29, for example. These approaches work, but the following technique produces caller-code that’s more obvious, easier to write, easier to read, and is generally more elegant.

The idea, called the Named Parameter Idiom, is to change the function’s parameters to methods of a newly created class, where all these methods return

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
30 by reference. Then you simply rename the main function into a parameterless “do-it” method on that class.

We’ll work an example to make the previous paragraph easier to understand.

The example will be for the “open a file” concept. Let’s say that concept logically requires a parameter for the file’s name, and optionally allows parameters for whether the file should be opened read-only vs. read-write vs. write-only, whether or not the file should be created if it doesn’t already exist, whether the writing location should be at the end (“append”) or the beginning (“overwrite”), the block-size if the file is to be created, whether the I/O is buffered or non-buffered, the buffer-size, whether it is to be shared vs. exclusive access, and probably a few others. If we implemented this concept using a normal function with positional parameters, the caller code would be very difficult to read: there’d be as many as 8 positional parameters, and the caller would probably make a lot of mistakes. So instead we use the Named Parameter Idiom.

Before we go through the implementation, here’s what the caller code might look like, assuming you are willing to accept all the function’s default parameters:

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
9

That’s the easy case. Now here’s what it might look like if you want to change a bunch of the parameters.

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
0

Notice how the “parameters”, if it’s fair to call them that, are in random order (they’re not positional) and they all have names. So the programmer doesn’t have to remember the order of the parameters, and the names are (hopefully) obvious.

So here’s how to implement it: first we create a class (

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
31) that houses all the parameter values as
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
75 data members. The required parameters (in this case, the only required parameter is the file’s name) is implemented as a normal, positional parameter on
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
31’s constructor, but that constructor doesn’t actually open the file. Then all the optional parameters (readonly vs. readwrite, etc.) become methods. These methods (e.g.,
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
34,
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
35, etc.) return a reference to their
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
9 object so the method calls can be chained.

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
1

The only other thing to do is make the constructor for class

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
37 to take an
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
31 object:

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
2

This constructor gets the actual parameters from the OpenFile object, then actually opens the file:

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
3

Note that

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
31 declares
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
37 as its
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
41, that way
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
31 doesn’t need a bunch of (otherwise useless)
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
43 get methods.

Since each member function in the chain returns a reference, there is no copying of objects and the chain is highly efficient. Furthermore, if the various member functions are

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
44, the generated object code will probably be on par with C-style code that sets various members of a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
45. Of course if the member functions are not
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
44, there may be a slight increase in code size and a slight decrease in performance (but only if the construction occurs on the critical path of a CPU-bound program; this is a can of worms I’ll try to avoid opening), so it may, in this case, be a tradeoff for making the code more reliable.

Why am I getting an error after declaring a void g() { List x(); // Function named x (that returns a List) // ... } 91 object via class Foo { public: Foo(char x); Foo(char x, int y); // ... private: void init(char x, int y); }; Foo::Foo(char x) { init(x, int(x) + 7); // ... } Foo::Foo(char x, int y) { init(x, y); // ... } void Foo::init(char x, int y) { // ... } 48?

Because that doesn’t create a

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object - it declares a non-member function that returns a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object. The term “Most Vexing Parse” was coined by Scott Myers to describe this situation.

This is really going to hurt; you might want to sit down.

First, here’s a better explanation of the problem. Suppose there is a class called

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
51 that has a default ctor. This might even be a library class such as
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
52, but for now we’ll just call it
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
51:

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
4

Now suppose there’s another class called

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 that has a ctor that takes a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
51. As before, this might be defined by someone other than you.

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
5

Now you want to create a

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object using a temporary
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
51. In other words, you want to create an object via
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
58, and pass that to the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 ctor to create a local
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 object called
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5:

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
6

It’s a long story, but one solution (hope you’re sitting down!) is to add an extra pair of

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
62s around the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
58 part:

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
7

Another solution is to use

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
87 in your declaration (see the fine print below):

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
8

Note: The above solution requires

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
65 to be able to access the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 copy constructor. In most situations that means the
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 copy constructor needs to be
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
77, though it needn’t be
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
77 in the less common case where
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
65 is a friend of
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
71. If you’re not sure what any of that means, try it: if your code compiles, you passed the test.

Here’s another solution (more fine print below):

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
9

Note: The word “usually” in the above means this: the above fails only when

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
72 constructor is
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73, or when
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91’s copy constructor is inaccessible (typically when it is
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
75 or
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
76, and your code is not a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
41). If you’re not sure what any of that means, take 60 seconds and compile it. You are guaranteed to find out whether it works or fails at compile-time, so if it compiles cleanly, it will work at runtime.

However, the best solution, the creation of which was at least partially motivated by the fact that this FAQ exists, is to use uniform initialization, which replaces the

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
62 around the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
58 call with
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
80 instead.

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
0

That’s the end of the solutions; the rest of this is about why this is needed (this is optional; you can skip this section if you don’t care enough about your career to actually understand what’s going on; ha ha): When the compiler sees

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
48, it thinks that the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
58 part is declaring a non-member function that returns a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
51 object, so it thinks you are declaring the existence of a function called
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
5 that returns a
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 and that takes as a single parameter of type “non-member function that takes nothing and returns a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
51.”

Now here’s the sad part. In fact it’s pathetic. Some mindless drone out there is going to skip that last paragraph, then they’re going to impose a bizarre, incorrect, irrelevant, and just plain stupid coding standard that says something like, “Never create temporaries using a default constructor” or “Always use

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
};

Foo::Foo(char x)
{
  // ...
  Foo(x, 0);  // Does NOT help initialize the this object!!
  // ...
}
87 in all initializations” or something else equally inane. If that’s you, please fire yourself before you do any more damage. Those who don’t understand the problem shouldn’t tell others how to solve it. Harumph.

(That was mostly tongue in cheek. But there’s a grain of truth in it. The real problem is that people tend to worship consistency, and they tend to extrapolate from the obscure to the common. That’s not wise.)

What is the purpose of the class Foo { public: Foo(char x); Foo(char x, int y); // ... private: void init(char x, int y); }; Foo::Foo(char x) { init(x, int(x) + 7); // ... } Foo::Foo(char x, int y) { init(x, y); // ... } void Foo::init(char x, int y) { // ... } 73 keyword?

The

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73 keyword is an optional decoration for constructors and conversion operators to tell the compiler that a certain constructor or conversion operator may not be used to implicitly cast an expression to its class type.

For example, without the

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73 keyword the following code is valid:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
1

But sometimes you want to prevent this sort of implicit promotion or implicit type conversion. For example, if

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 is really an array-like container and 42 is the initial size, you might want to let your users say,
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
92 or perhaps
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
93, but not just
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
94. If that’s the case, you should use the
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73 keyword:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
2

You can mix

class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73 and non-
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73 constructors and conversion operators in the same class. For example, this class has an
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73 constructor taking a
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
99 but a non-
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73 constructor taking a
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
01, and can be implicitly converted to double, but only explicitly converted to bool:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
3

The above code will print the following:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
4

Variable

class Foo {
public:
  Foo(char x, int y = 0);  // Has the effect of combining the two constructors
  // ...
};
10 is initialized using the
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
03 constructor because
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
04 cannot be used in an implicit cast, but
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
05 can be interpreted as a
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
06, that is, as
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
07, and implicitly cast to
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
91 using
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
09. This may or may not be what you intended, but this is what happens.

Why doesn’t my constructor work right?

This is a question that comes in many forms. Such as:

  • Why does the compiler copy my objects when I don’t want it to?
  • How do I turn off copying?
  • How do I stop implicit conversions?
  • How did my int turn into a complex number?

By default a class is given a copy constructor and a copy assignment that copy all elements, and a move constructor and a move assignment that move all elements. For example:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
5

Here we get

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
10 and
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
11. That’s often exactly what you want (and essential for C compatibility), but consider:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
6

Here, the default copy gives us

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
12 and
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
13. This leads to disaster: when we exit
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
3 the destructors for
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
15 and
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
16 are invoked and the object pointed to by
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
17 and
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
18 is deleted twice.

How do we avoid this? The simplest solution is to mark the operations that copy as deleted:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
7

If we need to copy or move, we can of course define the proper initializers and assignments to provide the desired semantics.

Now return to

void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
81. For
void g()
{
  List x();   // Function named x (that returns a List)
  // ...
}
81 the default copy semantics is fine, the problem is the constructor:

class Fred {
public:
  Fred(int i=3, int j=5);   // Default constructor: can be called with no args
  // ...
};
8

People provide default arguments to get the convenience used for

class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
21 and
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
22. Then, some are surprised by the conversion of
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
23 to
class Fred {
public:
  Fred();   // Default constructor: can be called with no args
  // ...
};
24 in the call of
class Fred {
public:
  Fred();
  // ...
};

int main()
{
  Fred a[10];              // Calls the default constructor 10 times
  Fred* p = new Fred[10];  // Calls the default constructor 10 times
  // ...
}
3. This constructor defines a conversion. By default that’s an implicit conversion. To require such a conversion to be explicit, declare the constructor
class Foo {
public:
  Foo(char x);
  Foo(char x, int y);
  // ...
private:
  void init(char x, int y);
};

Foo::Foo(char x)
{
  init(x, int(x) + 7);
  // ...
}

Foo::Foo(char x, int y)
{
  init(x, y);
  // ...
}

void Foo::init(char x, int y)
{
  // ...
}
73: