在静态变量的构造函数中检索静态const变量的值

时间:2010-04-14 19:51:55

标签: c++ static constructor static-variables

据我所知,下面的代码会导致分段错误,因为在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)
    {
    }

2 个答案:

答案 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是什么。

如果您交换AB的定义,那么代码应该编译并正常工作。只要所有内容都在同一个翻译单元中,初始化顺序就不应该有任何问题,假设B的静态成员的定义位于定义之前<{em> of C::s_A。在同一翻译单元中定义的对象按其定义的顺序初始化,这意味着在A::A()开始时,B的静态成员已经初始化。在这种情况下,没有可能出现分段错误。

如果您遇到分段错误,则必须采用不同的方式。定义顺序不同?可能有多个翻译单位?发布/描述真实代码。