【问题标题】:Order of constructor call in STLSTL中的构造函数调用顺序
【发布时间】:2016-04-23 03:37:48
【问题描述】:

最近看了简单的STL源码,代码如下:

#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;
}

输出:

deque()
stack()

当我创建一个堆栈对象时,它应该首先调用堆栈构造函数。但事实并非如此。

为什么编译器会先调用deque构造函数?

【问题讨论】:

  • 先处理模板。
  • @RetiredNinja 只涉及成员初始化的相对顺序;它不包括何时运行包含这些成员的类的构造函数
  • @RetiredNinja 非静态数据成员应按照在类定义中声明的顺序进行初始化,最后执行构造函数体的复合语句。答案对我很有用,谢谢!
  • 在代码也有 using namespace std; 的情况下编写名为 dequestack 的模板是很好的混淆方法,因为它们也是标准中的模板名称库(即,在命名空间std 中定义)。摆脱using namespace std;

标签: c++ constructor stl


【解决方案1】:

在进入构造函数体之前,会调用基类构造函数,然后所有非静态成员变量默认按照声明的顺序初始化,除非它们出现在成员初始化列表中。在您的代码中,Sequence c 首先被初始化,然后Stack::Stack() 的主体被执行。

这个程序说明了构建的顺序 - 销毁。

#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;
}

输出

静态成员
Base_1
Base_2
会员_1
非默认成员
会员_2
衍生
~派生
~会员_2
~成员非默认
~会员_1
~Base_2
~Base_1
~静态成员

【讨论】:

    猜你喜欢
    • 2014-01-28
    • 1970-01-01
    • 2012-08-22
    • 2013-06-24
    • 2013-01-29
    • 2011-11-24
    相关资源
    最近更新 更多