C ++类的静态成员在构造函数

时间:2015-08-19 16:20:53

标签: c++ static g++ global-variables static-libraries

我在构造函数之前没有初始化类的静态成员时遇到问题。难道我做错了什么?这是G ++中的错误吗? 任何解决方法?

g ++ --version:(Ubuntu 4.8.4-2ubuntu1~14.04)4.8.4
我也使用Eclipse作为我的IDE,但我只是将静态lib头文件复制到/usr/include/StaticTestLib/InitTest.h,将库复制到/usr/lib/x86_64-linux-gnu/libStaticTestLib.a

请注意,只有在main之前定义了保存数据的对象且类在静态库中时才会发生这种情况。

静态库头(静态库本身名为StaticTestLib):

InitTest.h
#include <iostream>
namespace StaticTestLib  {
    class notifier_header{
    public:
        notifier_header(){
            std::cout<<"static var init"<<std::endl;
        }
    };

    class InitTest {
    public:
        static notifier_header _header_notifier;
        InitTest();
        virtual ~InitTest();
    };    
}

静态库源文件:

InitTest.cpp
#include "InitTest.h"

namespace StaticTestLib  {
    notifier_header InitTest::_header_notifier;

    class notifier_cpp{
    public:
        notifier_cpp(){
            std::cout<<"code before constructor"<<std::endl;
        }
    }_notifier_in_cpp;

    InitTest::InitTest() {
        std::cout<<"constructor"<<std::endl;
    }

    InitTest::~InitTest() {
        std::cout<<"destructor"<<std::endl;
    }
}

这个程序:

StaticTest.cpp
#include <iostream>
#include <StaticTestLib/InitTest.h>

StaticTestLib::InitTest test;

int main() {
    std::cout << "program main" << std::endl;
    std::cout << "program end" << std::endl;
    return 0;
}

......输出:

constructor
static var init
code before constructor
program main
program end
destructor

但是这个程序:

#include <iostream>
#include <StaticTestLib/InitTest.h>

int main() {
    std::cout << "program main" << std::endl;
    StaticTestLib::InitTest test;
    std::cout << "program end" << std::endl;
    return 0;
}

......输出:

static var init
code before constructor
program main
contructor
program end
destructor

1 个答案:

答案 0 :(得分:1)

我的猜测是,这与未定义的不同编译单元中静态对象初始化的顺序有关。

您在test中创建main对象的第二个代码段很容易解释。静态初始化将始终在任何代码执行之前发生,因此当您输入main时,肯定会创建notifier_header对象。

现在,当您在test之前创建main时,您有两个静态对象。 notifier_header对象不依赖于您的InitTest:它在该类范围内,但它存储在静态内存中。您似乎引用了notifier_header中的InitTest.cppmain是与notifier_header不同的编译单元。如果没有相互依赖性,编译器可以为这两个单元以任何顺序自由地进行静态分配。

如果您的构造函数依赖于headerInstance,则可以将其用作单例。创建一个返回静态对象实例的函数(在下面的示例中为#include <iostream> namespace StaticTestLib { class notifier_header{ public: notifier_header(){ std::cout<<"static var init"<<std::endl; } }; class InitTest { public: InitTest(); virtual ~InitTest(); notifier_header& headerInstance(); }; } ),并在调用时创建对象:

#include "InitTest.h"

namespace StaticTestLib  {

class notifier_cpp{
public:
    notifier_cpp(){
        std::cout<<"code before constructor"<<std::endl;
    }
}_notifier_in_cpp;

InitTest::InitTest() {
    headerInstance();
    std::cout<<"constructor"<<std::endl;
}

InitTest::~InitTest() {
    std::cout<<"destructor"<<std::endl;
}

notifier_header& InitTest::headerInstance() {
    static notifier_header _header_notifier; // will only be constructed once
    return _header_notifier;
}

}

静态库源文件(InitTest.cpp)

static var init
constructor
code before constructor
program main
program end
destructor

我得到的输出:

!