【问题标题】:c++ variable/instance initializaiton order across different Translation units跨不同翻译单元的c ++变量/实例初始化顺序
【发布时间】:2016-02-16 14:29:10
【问题描述】:

提前致谢。

我在一些实际项目中看到了这些代码。我只是简化了它们来表达我的问题。基类将 this 指针放入其构造函数中的 vector(vec) 中。使用这个技巧,我们可以利用动态绑定在外部(在 main func 中)调用派生类的方法。关键是将向量定义放在Bash.h中,声明放在main.cpp中。

我的问题是,输出不是我想要的。为什么 vec 在一个 Translation 单元(base.c,我们可以看到大小为 1)中初始化并使用,然后在其他 Translation 单元(ma​​in.c,我们可以看到大小变成了0),是不是又被初始化清零了?我想知道不同翻译单元的初始化顺序。好像 Derive::dInstance 是第一位的,vec 是第二位的,但是为什么呢?

Base.h

#ifndef BASE_H
#define BASE_h

#include<iostream>
#include<vector>
using namespace std;
class Base{
    public:
        Base();
        virtual void speak();
};

#endif

Base.cpp

#include"Base.h"

vector<Base*> vec;
Base::Base() {
    vec.push_back(this);
    cout << "Base's constructor" << endl;
    cout << "Base() vector size: " << vec.size() << endl;**
}

void Base::speak() {
    cout << "I am Base" << endl;
}

导出.h

#ifndef DERIVE_H
#define DERIVE_h
#include<iostream>
#include"Base.h"

class Derive: public Base {
    public:
        Derive();
        virtual void speak();

        static Derive dInstance;
};
#endif

导出.cpp

#include "Derive.h"

// static member definition
Derive Derive::dInstance;

Derive::Derive() {
    cout << "Derived's construtor" << endl;**
}
void Derive::speak() {
    cout << "I am Derived" << endl;
}

main.cpp

#include<iostream>
#include"Base.h"

using namespace std;

extern vector<Base*> vec;
int main(int argc, char *argv[]) {
    cout << "vector size: " << vec.size() << endl;

    for(vector<Base*>::iterator iter = vec.begin(); iter != vec.begin(); iter++) {
        (*iter)->speak();
    }
}

输出:

Base的构造函数 Base() 向量大小:1 Derived 的构造函数 main() 向量大小:0

【问题讨论】:

    标签: c++ design-patterns initialization singleton translation-unit


    【解决方案1】:

    这是“static initialization order fiasco”。

    translation units 和 static(或全局)变量之间的初始化顺序未定义。所以想想如果Derived.cpp 文件在Base.cpp 之前初始化会发生什么,然后你添加一个未初始化(构造)的向量导致未定义的行为,然后 em> 向量已初始化。

    【讨论】:

    • 感谢您的回复。但是如果我用变量替换向量(例如 int a),在这里重复相同的东西,一切都很好。
    【解决方案2】:

    起初,不同翻译单元之间的初始化顺序没有规则。

    并且,全局变量和全局静态变量将在主函数之前初始化。属于函数 FuncA() 的局部静态变量将在第一次调用 FuncA() 时被初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-27
      相关资源
      最近更新 更多