-2
class ClassObject {
public:
    ClassObject();
    virtual ~ClassObject();
private:
    int x;
 };

int ClassObject::x=10;

Why does it fail to compile? I think that if static members can be initialized this way, then it should also be possible for non-static ones.

Mixhab
  • 421
  • 3
  • 14
jiafu
  • 6,338
  • 12
  • 49
  • 73
  • 6
    What makes you think that? – David G Apr 29 '13 at 23:57
  • But if it's non-static it needs to be set on an object and there's no object here. ... or do you mean the default value for initialisation when you create a new object, i.e. moving this code out of the constructor? – Rup Apr 29 '13 at 23:58
  • what if i want `x` to be something other than 10? – yngccc Apr 29 '13 at 23:58
  • 1
    check out this post: http://stackoverflow.com/questions/9656941/why-i-cant-initialize-non-const-static-member-or-static-array-in-class – taocp Apr 29 '13 at 23:58
  • @tacp That's the opposite case isn't it? Except maybe this bit at the bottom: "Also, C++11 will allow(§12.6.2.8) a non-static data member to be initialized where it is declared(in its class). This will mean much easy user semantics." although that's not exactly what's in the question. – Rup Apr 30 '13 at 00:00
  • You may *think* that, but can you actually provide any *supporting arguments* or do you we have to take your "thoughts" at face value and go ahead and change the language? – Nik Bougalis Apr 30 '13 at 00:30

2 Answers2

6

Static members are special. They have a memory allocated to them as soon as the class is defined. And no matter how many objects of that class we create all those objects refer to the same piece of memory.

This is not the case with non static members. Unless you create an object of that particular class, the non static members are not allocated any memory and hence trying to instantiate them in the above way leads to compiler error.

csurfer
  • 296
  • 1
  • 7
0

I'm guessing you mean declaring the value used to initialise x for any new ClassObject, i.e. you mean that as equivalent to

ClassObject() : x(10) { }

The problem with your syntax is that the compiler needs to generate code to do that initialisation in every ClassObject constructor; i.e. it can only work if the int ClassObject::x = 10; initialisation is available in the compilation unit that defines all constructors, and any compilation units that generate one implicitly. And the only way to guarantee that is if the value is set inside the class definition, not outside it as you have. (However this is now possible in C++11 - see the link in tacp's comment.)

If we did want to make your syntax work, then we'd need to store the declared value as a hidden static somewhere in a way that any constructors would pick it up and know to use it as the initial value for x. However this static may or may not exist, and the only point we can know that for a constructor in a different compilation unit is at link time. Hence we either generate extra, redundant code to initialise x from this hidden static if it exists (or redundant data) or we mandate link-time-code-generation to solve this, which puts a large burden on the compiler developer. It is possible, yes, but it's simpler all around if this isn't allowed.

Rup
  • 33,765
  • 9
  • 83
  • 112