据我所知,下面的代码会导致分段错误,因为在A的cstr处,B :: SYMBOL尚未初始化。但为什么呢?
实际上,A是一个对象,用作将B类等的SYMBOL映射到各自ID的映射。 C静态地保存这个映射(A),使得它可以提供映射作为类函数。
A的主要功能是作为C的映射,在启动时初始化自身。如果我仍然可以在代码中使用B :: ID和B :: SYMBOL(没有#define pls),我怎么能在没有分段错误的情况下做到这一点?
(ps。假设我已经实施了包含警卫)
//A.h
#include "B.h"
class A
{
public:
A()
{
std::cout<<B::ID<<std::endl;
std::cout<<B::SYMBOL<<std::endl;
}
};
//B.h
class B
{
public:
static const int ID;
static const std::string SYMBOL;
}
//B.cpp
#include "B.h"
const int B::ID = 1;
const std::string B::SYMBOL = "B";
//C.h
#include "A.h"
class C
{
public:
static A s_A;
};
//C.cpp
#include "C.h"
A C::s_A;
//main.cpp
#include "C.h"
int main(int c, char** p)
{
}
答案 0 :(得分:1)
使用s_A的延迟初始化。这可能有效:
class C
{
public:
static A& getA() { static A s_A; return s_A; }
};
或者:
class C
{
public:
static A& getA()
{
if( ps_A == NULL) ps_A = new ps_A;
return *ps_A;
}
private:
static A* ps_A;
};
A* C::ps_A = NULL;
这两种解决方案都不是线程安全的。
答案 1 :(得分:1)
你在说什么分段错误?您的代码根本无法编译,因为B
(和B
本身)的成员在A::A()
之前未声明。编译器根本不知道B
是什么。
如果您交换A
和B
的定义,那么代码应该编译并正常工作。只要所有内容都在同一个翻译单元中,初始化顺序就不应该有任何问题,假设B
的静态成员的定义位于定义之前<{em> of C::s_A
。在同一翻译单元中定义的对象按其定义的顺序初始化,这意味着在A::A()
开始时,B
的静态成员已经初始化。在这种情况下,没有可能出现分段错误。
如果您遇到分段错误,则必须采用不同的方式。定义顺序不同?可能有多个翻译单位?发布/描述真实代码。