【问题标题】:Defining private static class member定义私有静态类成员
【发布时间】:2011-01-02 18:28:10
【问题描述】:
class B { /* ... */ };

class A {
public:
    A() { obj = NULL; }
private:
    static B* obj;
};

但是,这会产生大量链接器错误,符号 obj 未解决。

在没有这些链接器错误的情况下,拥有这样的私有静态类成员的“正确”方法是什么?

【问题讨论】:

    标签: c++ class static member


    【解决方案1】:

    你需要这样定义:

    这是在标题中:

    class B { ... }
    
    class A {
    public:
        A() { obj = NULL; }
    private:
        static B* obj;
    }
    

    这是在源代码中

    B* A::obj = NULL;
    

    【讨论】:

    • 那么他很可能不需要A() { obj = NULL; }
    • @7vies:不包括 A 构造函数会改变代码的含义。目前,新 A 对象的构造会重置静态成员 obj(这可能很重要)。
    • @Martin:虽然我同意从构造函数中取出静态成员的初始化会改变行为,但我很好奇为什么有人会向潜在的内存泄漏敞开心扉,这可能(并且可能会) 原因。如果任何 A 对象在堆上创建了 B 对象,那么下次创建 A 对象时,B 对象就会被泄露。
    【解决方案2】:

    你需要添加

    B *A::obj = NULL;
    

    到您的 cpp 文件之一。另请注意,如果您在 A 的构造函数中设置 obj,这意味着每当您创建 A 对象时,您都会再次重置 obj - 因为它是静态的,所以所有 A 实例之间只有一个 obj 共享。

    【讨论】:

      【解决方案3】:

      http://www.parashift.com/c++-faq/ctors.html#faq-10.12

      (正如@peoro 所说,请记住以; 结束每个类定义。

      【讨论】:

      • @7vies:这就是为什么那部分是带括号的 PS。
      • 好吧,即使在括号中也没有多大意义,因为他已经知道了
      【解决方案4】:

      你必须在一个 cpp 文件中初始化 obj:

      B* A::obj = NULL;
      

      你不能在构造函数中初始化它,因为它是一个静态变量。

      【讨论】:

      • 碰巧的是,他正在分配给它,而不是尝试在构造函数中初始化它,这就是为什么他得到链接器而不是编译器错误的原因。
      【解决方案5】:

      你声明了静态成员,但你没有定义它。

      此外,只要构造 A 的任何实例,您就设置它的值,而实际上您只希望它初始化一次。

      class B;
      
      class A {
      private:
          static B* obj;
      };
      
      B* A::obj = NULL;
      

      由于您的 A 类定义可能在头文件中,您应该确保 obj(我添加的)的定义放在一个(并且只有一个).cpp 文件中。这是因为它在你编译的项目中只能出现一次,而头文件的内容可能是#included多次。

      【讨论】:

        【解决方案6】:

        链接错误是因为您还需要在类定义之外声明静态变量,纯粹用于链接目的和静态内存分配

        B* A::obj;
        

        【讨论】:

          猜你喜欢
          • 2014-09-02
          • 2011-02-24
          • 2015-09-26
          • 1970-01-01
          • 2017-10-20
          • 2020-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多