Tag Archives: Constructor

Lifetime of local static variables

Local static variables are constructed when the program flow first encounters their constructor call. This means that if control does not reach it, they will not be constructed.
They are destroyed at the end of the program. As with all objects, local statics are destroyed in reverse order of their creation.

#include <iostream>
#include <string>

struct Announcer {
    Announcer(const std::string& str) 
        : msg(str)
    {
        std::cout << "Created " << msg << "\n";
    }
    ~Announcer() 
    { 
        std::cout << "Destroyed " << msg << "\n";
    }
    std::string msg;
};

void func(bool condition) 
{
    if (condition) {
        static Announcer a1("in condition");
    }
    static Announcer a2("in func");
}

int main(int argc, char *argv[])
{
    func(argc > 1);
}

Running this without an argument produces:

Created in func
Destroyed in func

Because the code never enters the conditional in func(), a1 is never created.
Running it with an argument produces:

Created in condition
Created in func
Destroyed in func
Destroyed in condition

Here, the conditional has been entered, so a1 is created. Note the order of the destructor calls – in revese order to the order of construction.

Calling the base class constructor in C++

The default base class constructor will automatically be called by a derived class default constructor.
If you need to call another base class constructor, you need to put the call to it in the derived class initializer list:


class Base
{
public:
    Base(int i)
        i_(i)
    {
    }
private:
    int i_;
};

class Derived : public Base
{
public:
    Derived(int i, j)
        : Base(i), j_(j)
    {
    }
private:
    int j_;
};

See Typedef super for a handy idiom for referring to the base class.

Calling One Constructor from Another in C++

C++11 has added the ability to call one constructor from another, allowing you to combine the code in constructors. You just call the second constructor from the initialization list of the first:

class Fruit
{
public:
    Fruit(const std::string& name, int number)
        : name_(name), number_(number)
    {
    }
    Fruit(const std::string& name)
        : Fruit(name, -1)
    {
    }
private:
    std::string name_;
    int number_;
};

Unfortunately, there isn’t a way of doing this in C++03. Putting a constructor call in the initialization list is a syntax error, while putting it in the body of the constructor just creates a temporary object.

    Fruit(const std::string& name)
    {
        Fruit(name, -1); // This just creates a temporary object
    }

You can, however, combine constructors by using default parameters:

    Fruit(const std::string& name, int number=-1)
        : name_(name), number_(number)
    {
    }

Or you can do your initialization in an Init() function and have your constructors delegate to that:

    Fruit(const std::string& name, int number)
    {
        Init(name, number);
    }
    Fruit(const std::string& name)
    {
        Init(name, -1);
    }
    void Init(const std::string& name, int number)
    {
        name_ = name;
        number_ = number;
    }

There are a few disadvantages to the Init() method:

  • The fields will be default initialized in the constructor before being initialized again in the Init() function
  • The values initialized in the Init() function cannot be passed to base class constructors that need them because it’s too late at that point (although the base class itself might have an Init function)
  • You can’t initialize const pointer or reference members this way, because they need to be initialized in the initialization list