2

As we know,It is possible to initialize integral const static members inside the class structure.This is useful when the constant is used in the class structure after the initialization.For example,it can be used as the size of an int array. Look the code following:

class MyClass{
static const int num = 100;
int elems[num];
...
};

But we still have to define the member num outside the class definition:

const int MyClass::num;

I don't know why we have to do like this. Could someone tell me why? Thanks a lot.

In addition,I write the following code:

#include <iostream>
using namespace std;

class MyClass{
public:
MyClass()
{
    cout << "instruct class MyClass!" << endl;
}
static const int num = 100;
int elems[num];
};

//const int MyClass::num;

int main()
{
MyClass a;
const int *b = &(a.num);
cout << "&(a.num): " << &(a.num) << endl;
cout << "a.num: " << a.num << endl;
cout << "*b: " << *b << endl;
}

It runs well on Visual Studio 2008:

enter image description here

But I have removed the code that definite the member num outside the class.

I am very confused.Could someone interpret it for me?

0

2 Answers 2

5

The initialization in the class is mainly used to obtain a constant expression. For this only the value matters. Once you take the address of the object or bind it to a reference, the compiler needs a location for the object as well. This is effectively what the definition provides.

3
  • 1
    But the compiler could handle it in the same way it handles static members of templates, or inline functions, both of which have definitions in multiple files, but still require a single address. Commented Mar 20, 2012 at 11:54
  • @JamesKanze: for static members of templates you still need a definition which actually quite annoying because implicit instantiations don't work for this. It could be made to behave like static variables in inline functions, I guess. My understanding is that these work by creating functions with weak symbols which get discarded at link-time. However, the language currently requires the definition although compilers may not insist on it being present. Commented Mar 20, 2012 at 12:03
  • I know. I'm just saying that technically, it wouldn't be a problem to not require the definition, since the compiler technology to support not requiring it is necessary in other contexts as well. Commented Mar 20, 2012 at 12:21
4

You would need to define the static constant num outside the class in a cpp file only if your code takes it's address.This is known as an Out-of-class definition.
If your code does not take address of num, then the In-class Initialization would just work fine.

Rationale:

Bjarne states:

"C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects."

Note that only static const integers can be treated as compile time constants. The compiler knows that the integer value will not change anytime and hence it can apply its own magic and apply optimizations, the compiler simply inlines such class members i.e, they are not stored in memory anymore, As the need of being stored in memory is removed, it gives such variables the exception to the above rule mentioned by Bjarne.

Even if static const integral values can have In-Class Initialization, taking address of such variables is not allowed. One can take the address of a static member if (and only if) it has an out-of-class definition because then the compiler needs to place them in memory.

1
  • Finally I understand. Thank you so much!I am very appreciated for your reply!
    – XiaJun
    Commented Mar 21, 2012 at 3:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.