2010-04-27 124 views
4

我有一个奇怪的问题,显然没有被初始化,因为它应该是一个静态变量。
我有一个运行Windows和Linux的巨大项目。由于Linux开发人员没有这个问题,我建议这是某种有线Visual Studio的东西。

头文件静态变量未初始化

class MyClass 
{ 
    // some other stuff here 
    ... 
    private: 
     static AnotherClass* const Default_; 
}; 


CPP文件

AnotherClass* const MyClass::Default_(new AnotherClass("")); 
MyClass(AnotherClass* const var) 
{ 
    assert(Default_); 
    ... 
} 

问题是,Default_总是NULL。我也在该变量的初始化时尝试了一个断点,但我无法捕捉到它。

另一个班有类似的问题。
CPP文件

std::string const MyClass::MyString_ ("someText"); 
MyClass::MyClass() 
{ 
    assert(MyString_ != ""); 
    ... 
} 

在这种情况下MyString_总是空的。所以再次没有初始化。
有没有人有关于此的想法?这是一个Visual Studio设置问题吗?
干杯西蒙

编辑:
我也遇到了静态初始化惨败。但我不确定这是否会成为问题,因为Linux编译器没有问题。编译器在这种情况下不应该以同样的方式作出反应吗?

+0

尝试从头开始创建一个新项目,看看它是否发生在那里以及 – shoosh 2010-04-27 10:57:00

+0

对不起,不行。正如我所说这是一个非常大的项目。 – 2010-04-27 10:57:43

+1

我假设第一个例子是一个错字,应该是'AnotherClass * const MyClass :: Default_(new AnotherClass(“”));' – 2010-04-27 10:59:22

回答

6

我建议你使用静态变量,而不是静态变量本身静态成员函数:

class MyClass 
{ 
    // some other stuff here 
    ... 
    private: 
     static AnotherClass* const getAnotherClass(); 
}; 

AnotherClass *const MyClass::getAnotherClass() 
{ 
    static AnotherClass *const p = new AnotherClass(""); 
    return(p); 
} 

标准的保证,当函数被调用首次p被初始化一次,所以你总是会得到正确初始化的对象(除非你已经耗尽内存或构造函数抛出)。

请注意 - 这可能是也可能不是线程安全的(取决于你的编译器)。

还有一个注意事项 - 现在你必须忍受“内存泄漏”,因为它几乎不可能决定何时销毁对象,并且你没有办法将p重置为NULL。

+0

在这种情况下使用指针是不好的。一个简单的实例化,然后返回一个引用会好得多。毕竟,一旦你删除了NULL的可能性,是不是'* const'语义等价于'&'? – 2010-04-27 14:45:10

+0

@Matthieu:我只是按照给出的代码。对于你的评论 - 你可能是对的,但它取决于AnotherClass的功能(例如,它可能会占用数据段中的所有空间,所以没有其他全局变量可用)。 – Tomek 2010-04-27 18:04:21

+0

我同意为了不使数据段或堆栈饱和(我希望这里有'Go'这样的......),可能需要使用*堆*,但是我认为它应该被保留为特殊情况(大对象)并推迟到必要时。 – 2010-04-28 06:19:30

0

作品在我的机器(TM):

#include <iostream> 
#include <cassert> 

class AnotherClass 
{ 
public: 
    AnotherClass(const char*) {} 
}; 

class MyClass 
{ 
public: 
    MyClass(AnotherClass* const var); 
private: 
    static AnotherClass* const Default_; 
}; 

AnotherClass* const MyClass::Default_(new AnotherClass("")); 

MyClass::MyClass(AnotherClass* const var) 
{ 
    assert(Default_); 
    std::cout << "Worked!\n"; 
} 

int main() 
{ 
    MyClass tester(NULL); 
    return 0; 
} 

我想的问题是,被称为另一个静态变量的构造。静态变量的初始化并不总是以你想要的顺序发生。

+0

但在他的第二个例子中,他记得'MyClass ::',所以它可能只是一个错字。 – 2010-04-27 11:00:21

+0

是的,它应该是,只是一个错字,但谢谢。 – 2010-04-27 11:00:44

+0

你的例子也适用于我。 – 2010-04-27 11:14:59

3

如果在初始化其他一些静态变量时发生这种情况,您可能会看到static initialization fiasco

+0

这是一个Visual Studio编译器相关的问题?或者一个普遍的问题? – 2010-04-27 11:19:56

+0

@Simon:这是一个普遍问题。 – sth 2010-04-27 11:42:41

+0

所以它不能成为我的问题,因为Linux开发人员没有类似的问题... – 2010-04-27 11:45:03

2

不应该在这种情况下编译器反应相同的方式吗?

不,据我了解,个别编译单元的初始化顺序是UNDEFINED。所以Linux开发者很幸运。今天。明天,谁知道?