繁体   English   中英

不同翻译单元之间的c ++变量/实例初始化顺序

[英]c++ variable/instance initializaiton order across different Translation units

提前致谢。

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

我的问题是,输出不是我想要的。 为什么将vec初始化并在一个转换单元( base.c ,我们看到大小为1)中使用,然后在其他转换单元( main.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;
}

Derive.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

Derive.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's constructor
Base() vector size: 1
Derived's constructor
main() vector size: 0

这是static初始化顺序惨败”

未定义static (或全局)变量的转换单元之间的初始化顺序。 所以,想想,如果发生了什么Derived.cpp前文件被初始化Base.cpp ,然后添加到导致不确定的行为未初始化向量(构建), 那么矢量被初始化。

起初,对于初始化顺序没有规定不同翻译单元的规则。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM