为什么静态成员需要从类中初始化

时间:2018-08-02 04:30:59

标签: c++ static

#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,为什么需要在类之外对其进行定义?

谢谢。

2 个答案:

答案 0 :(得分:3)

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

原因是定义只能在一个translation unit内完成。

如果静态成员变量在头文件中定义,则可以多次定义one definition rule

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

答案 1 :(得分:1)

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

请尝试以下示例。

#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;
 }