【问题标题】:Retrieving values of static const variables at a constructor of a static variable在静态变量的构造函数中检索静态 const 变量的值
【发布时间】:2010-04-14 19:51:55
【问题描述】:

我知道下面的代码会导致分段错误,因为在 A 的 cstr 处,B::SYMBOL 尚未初始化。但为什么呢?

实际上,A 是一个用作映射的对象,它将 B 等类的符号映射到它们各自的 ID。 C 静态地保存这个 map(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)
    {
    }

【问题讨论】:

    标签: c++ static constructor static-variables


    【解决方案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;
    

    这两种解决方案都不是线程安全的。

    【讨论】:

      【解决方案2】:

      你在说什么分段错误?您的代码根本无法编译,因为B(和B 本身)的成员没有在A::A() 之前声明。编译器根本不知道B 是什么。

      如果您交换A 和B 的定义,那么代码应该可以编译并正常工作。只要一切都在同一个翻译单元中,初始化顺序应该没有任何问题,假设B的静态成员的定义在定义之前C::s_A 的 em>。在同一个翻译单元中定义的对象按照它们的定义顺序进行初始化,这意味着在A::A() 开始时,B 的静态成员已经被初始化。在这种情况下,没有出现分段错误的可能性。

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

      【讨论】:

      • 在我的代码中,我将它们放入头文件并正确执行包含。因此,它们不在同一个翻译单元中,因为它们实际上是写在不同的文件中。
      • @gilbertc:嗯,在初始化全局变量和静态变量时,它们是否在同一个 TU 中确实会有所不同。因此,您最好将您的示例调整为实际重现问题的内容。
      猜你喜欢
      • 1970-01-01
      • 2013-12-28
      • 2016-06-23
      • 2021-07-06
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      相关资源
      最近更新 更多