1

I recently read simple STL sources,Here is the code:

#include <iostream>
#include <cstddef>

using namespace std;

class alloc
{

};

template <typename T, typename Alloc = alloc, size_t Bufsiz = 0>
class deque
{
public:
    deque() { cout << "deque()" << endl; }
};

template <typename T, typename Sequence = deque<T> >
class stack
{
public:
    stack() { cout << "stack()" << endl; }
private:
    Sequence c;
};


int main()
{
    stack<int> x;

    return 0;
}

The output:

deque()
stack()

When i created a stack object,it should have called stack constructor first.But the fact is not.

Why the compiler calls deque constructor first?

Superxy
  • 147
  • 1
  • 8
  • The template is processed first. – Luc Apr 23 '16 at 03:43
  • 1
    Possible duplicate of [Order of member constructor and destructor calls](http://stackoverflow.com/questions/2254263/order-of-member-constructor-and-destructor-calls) – Retired Ninja Apr 23 '16 at 03:48
  • @RetiredNinja that one only covers relative order of member initialization; it doesn't cover when the constructor of the class containing those members is run – M.M Apr 23 '16 at 04:02
  • @RetiredNinja non-static data members shall be initialized in the order they were declared in the class definition,Finally, the compound-statement of the constructor body is executed. The answer is very usefull to me, thank you! – Superxy Apr 23 '16 at 04:03
  • Writing templates named `deque` and `stack` when the code also has `using namespace std;` is a **great** recipe for confusion, since those are also names of templates in the standard library (i.e., defined in namespace `std`). Get rid of `using namespace std;`. – Pete Becker Apr 23 '16 at 11:56

1 Answers1

4

Before you enter the body of a constructor, base class constructors are called, then all non-static member variables are default initialized in the order of declaration, unless they appear in a member initialization list. In your code Sequence c is initialized first and then the body of Stack::Stack() is executed.

This program illustrates the order of construction - destruction.

#include <iostream>
#include <string>

using namespace std;

struct Base_1
{
    Base_1()
    {
        cout << "Base_1\n";
    }
    ~Base_1()
    {
        cout << "~Base_1\n";
    }
};

struct Base_2
{
    Base_2()
    {
        cout << "Base_2\n";
    }
    ~Base_2()
    {
        cout << "~Base_2\n";
    }
};

struct Member_1
{
    Member_1()
    {
        cout << "Member_1\n";
    }
    ~Member_1()
    {
        cout << "~Member_1\n";
    }
};

struct Member_2
{
    Member_2()
    {
        cout << "Member_2\n";
    }
    ~Member_2()
    {
        cout << "~Member_2\n";
    }
};

struct Member_non_default
{
    Member_non_default( string s )
    {
        cout << "Member non default\n";
    }
    ~Member_non_default()
    {
        cout << "~Member non default\n";
    }
};

struct Static_member
{
    Static_member()
    {
        cout << "Static member\n";
    }
    ~Static_member()
    {
        cout << "~Static member\n";
    }
};

struct Derived: Base_1, Base_2
{
    Member_1 m1;
    Member_non_default m;
    Member_2 m2;
    static Static_member sm;

    Derived():
        m { "Member non default\n" }
    {
        cout << "Derived\n";
    }
    ~Derived()
    {
        cout << "~Derived\n";
    }
};

Static_member Derived::sm;

int main()
{
    Derived d;
}

Output

Static member
Base_1
Base_2
Member_1
Member non default
Member_2
Derived
~Derived
~Member_2
~Member non default
~Member_1
~Base_2
~Base_1
~Static member