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

Without out-of-class initialization there will be unresolved externals linker error.

But what is the reason for that? The class declaration specifies it as a static member and I am not even assigning a value n:

int X::n;

When I print it, n has the value 0. So it is default initialized.

If so, then what is the need and why the compiler cannot do the default initialization from the class declaration only? Compiler clearly can see that class X has a static int member n, why it needs to be defined out of the class?

Thank you.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
madu
  • 5,232
  • 14
  • 56
  • 96
  • 1
    You are talking about *definitions*. The word "initialization" means providing an initial value, which you don't do here. – M.M Aug 02 '18 at 05:11
  • 2
    People answered. By changing the question completely, you make their answers invalid, and future people coming here won't really get what the hell their answers have to do with the question. If you have a new question, there is an ["ask qeustion"](https://stackoverflow.com/questions/ask) button right there at the top. I rolled back your edits. – StoryTeller - Unslander Monica Aug 02 '18 at 07:22

2 Answers2

3

What you call initialization is really a definition.

And the reason is that definitions can only be done once is a single translation unit.

If the static member variable were defined in the header file it could be defined multiple times breaking the one definition rule.

Or the compiler would not know which translation unit to put the definition in, since it doesn't know anything about other possible translation units.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thank you. So if I am understanding this right, I can put the class definition in a header file, then I can use this class 'X' in multiple translation units, with each translation unit initializing X::n to a different value? – madu Aug 02 '18 at 04:46
  • 1
    @madu He meant that the definition "can only be done once in the whole program", or equivalently "there can only be a definition in one translation unit (and no others)" – M.M Aug 02 '18 at 05:13
  • Thank you M.M. I edited the the question to reflect this. Now I understand. One translation unit means one program essentially. Not one object file. – madu Aug 02 '18 at 05:16
  • 1
    @madu No, a translation unit is basically a *single source file* (with all headers included). I.e. what basically becomes an object file. When you link multiple object files together, there can be only one definition of e.g. static member variables, spread over all object files. Typically this definition is in a single object file. – Some programmer dude Aug 02 '18 at 05:38
  • Thank you. I've had a wrong idea about the translation unit. Thought a single object file is a single translation unit, and each translation unit can have it's own initialization for the static variables. Thank you for the clarification. – madu Aug 02 '18 at 05:55
1

A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present. We can't put it in the class definition but it can be initialized outside the class as done in the following example by redeclaring the static variable, using the scope resolution operator :: to identify which class it belongs to.

Try below example.

#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;
 }
Ankita Mehta
  • 442
  • 3
  • 16