【问题标题】:Why static members need to be initialized out of the class [duplicate]为什么需要从类中初始化静态成员[重复]
【发布时间】:2018-08-02 15:19:58
【问题描述】:
#include "stdafx.h"
#include <iostream>

class X { 
public:
    static int n; 
}; 
int X::n;  // out-of-class initialization 

int _tmain(int argc, _TCHAR* argv[])
{
    X x;
    std::cout << x.n << std::endl;
    return 0;
}

如果没有类外初始化,将会出现未解决的外部链接器错误。

但这是什么原因呢?类声明将其指定为静态成员,我什至没有分配值 n:

int X::n;

当我打印它时,n 的值为 0。所以它是默认初始化的。

如果是这样,那么需要什么以及为什么编译器不能仅从类声明中进行默认初始化?编译器可以清楚地看到类X有一个静态int成员n,为什么需要在类外定义?

谢谢。

【问题讨论】:

  • 你在谈论定义。 “初始化”这个词的意思是提供一个初始值,这里不做。
  • 人们回答了。通过完全改变问题,您使他们的答案无效,未来来到这里的人将不会真正了解他们的答案与问题有什么关系。如果您有新问题,顶部有一个"ask qeustion" 按钮。我回滚了你的编辑。

标签: c++ static


【解决方案1】:

你所说的初始化实际上是一个定义

原因是定义只能完成一次是单个translation unit

如果静态成员变量是在头文件中定义的,它可以被定义多次打破one definition rule

或者编译器不知道将定义放入哪个翻译单元,因为它对其他可能的翻译单元一无所知。

【讨论】:

  • 谢谢。因此,如果我理解这一点,我可以将类定义放在头文件中,然后我可以在多个翻译单元中使用这个类“X”,每个翻译单元将 X::n 初始化为不同的值?
  • @madu 他的意思是定义“在整个程序中只能做一次”,或者相当于“在一个翻译单元中只能有一个定义(不能在其他翻译单元中)”
  • 谢谢MM。我编辑了问题以反映这一点。现在我明白了。一个翻译单元本质上就是一个程序。没有一个目标文件。
  • @madu 不,翻译单元基本上是一个单个源文件(包括所有标题)。 IE。基本上变成了一个目标文件。当您将多个目标文件链接在一起时,只能有一个定义,例如静态成员变量,分布在所有目标文件中。通常,此定义位于单个对象文件中。
  • 谢谢。我对翻译单元有一个错误的想法。认为单个目标文件是单个翻译单元,每个翻译单元都可以对静态变量进行自己的初始化。谢谢你的澄清。
【解决方案2】:

类的所有对象共享一个静态成员。如果不存在其他初始化,则在创建第一个对象时将所有静态数据初始化为零。我们不能将它放在类定义中,但可以在类外部初始化它,如下例所示,通过重新声明静态变量,使用范围解析运算符 :: 来识别它属于哪个类。

试试下面的例子。

#include <iostream>

using namespace std;

class Box {
  public:
  static int objectCount;

  // Constructor definition
  Box(double l = 2.0, double b = 2.0, double h = 2.0) {
     cout <<"Constructor called." << endl;
     length = l;
     breadth = b;
     height = h;

     // Increase every time object is created
     objectCount++;
  }
  double Volume() {
     return length * breadth * height;
  }

 private:
  double length;     // Length of a box
  double breadth;    // Breadth of a box
  double height;     // Height of a box
 };

 // Initialize static member of class Box
 int Box::objectCount = 0;

int main(void) {
    Box Box1(3.3, 1.2, 1.5);    // Declare box1
    Box Box2(8.5, 6.0, 2.0);    // Declare box2

  // Print total number of objects.
   cout << "Total objects: " << Box::objectCount << endl;

  return 0;
 }

【讨论】:

    猜你喜欢
    • 2013-07-12
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多