2

I always read initialization list is preferred over constructor body for variable initialization. I also know that static variable can be initialized outside the class when defiling them.

But my question is why we can't initialize static variable in constructor initialization list , but we can in constructor body

class sample
{
    static int i;
public:
    sample (int ii=20) { i=ii;}
    void show()
    {
        cout << i << endl;
    }

};

int sample::i=12;

int main()
{
    sample s;
    s.show();
    return 0;
}

works fine and prints 20. but i replace constructor with

sample (int ii=20): i(ii){}

It gives error. Why?

Devesh Agrawal
  • 8,982
  • 16
  • 82
  • 131
  • 4
    You are not initializing it in the constructor body. You are *assigning* it a value. – juanchopanza Jan 11 '15 at 09:57
  • Because that is the way C++ is defined: you can only initialize non-static member variables after the `:` and before the `{` – Basile Starynkevitch Jan 11 '15 at 09:58
  • 1
    Has everybody misread the question? They want to know why you can't initialise a static member in the member initialisation list. – Joseph Mansfield Jan 11 '15 at 10:03
  • Does this answer your question? [How to initialize private static members in C++?](https://stackoverflow.com/questions/185844/how-to-initialize-private-static-members-in-c) – NAND Jun 04 '20 at 17:39

3 Answers3

6

Within the constructor's body, you assign. Initialization can only be done in the intializion list.

What you think is initializing the static member is just an assignment to it. You can test it yourself: Make the static member const, and your constructor will not be valid anymore.

Then, the constructor intialization list only applies to instance members. However, a static member is not a member of an instance of your class, but rather a global variable with the same visibility as other class members; therefore, any attempt to "initialize" them in the class initialisation list would actually be "re-initialization" of the static member, which is forbidden in C++.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
  • Does this really answer the question? Looks like they want to know the opposite. Why *can't* you initialise a static member in the member initialisation list? – Joseph Mansfield Jan 11 '15 at 10:02
  • 1
    @JosephMansfield I read the question as not understanding the difference between initialising in the init list and initalising in the body. Explaining why initialising in the init list is not possible is a valid way of answering that, explaining why initialising in the body is not even happening is another valid way of answering that. –  Jan 11 '15 at 10:13
  • @JosephMansfield: Yes to what hvd wrote. However, I realise that confusion may arise, and edited my answer accordingly. – Sebastian Mach Jan 11 '15 at 10:25
6

A member initialisation list denotes initialisation. A static member is already initialised at the beginning of your program (before main). If you could do what you are suggesting, you would be "re-initialising" the static member with every sample object that you create, but objects are only initialised once.

Instead, if you want to change the value of an object after it has been initialised, you have to assign to it. That's exactly what your first code is doing with i = ii;.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • _A static member is already initialised before your program starts_ is wrong in many contexts. Static members need not be compile time constants. – Sebastian Mach Jan 11 '15 at 10:24
  • @phresnel static variables are initialized before `main`, which typically contains the "program", so yes, static member and static global variables are initialised before the "program" starts. Only function local statics are an exception to this rule. – rubenvb Jan 11 '15 at 10:29
  • @phresnel Well it depends on how you interpret "before your program starts" - but I've rephrased it. – Joseph Mansfield Jan 11 '15 at 10:29
  • @rubenvb: If there is execution of code before main starts, then what can this be called, if not "a running program"? The Magic Pony Phase? Sincerely disagree with you. And on an operating system level, running the _program_ includes any _runtime_ initialization. – Sebastian Mach Jan 11 '15 at 10:34
  • 1
    @phresnel That's a little pedantic. Even if the initialiser were evaluated at compile-time, the actual object doesn't exist until you execute your program, so even that wouldn't be "before the program starts". I think it's commonly accepted that, in this context, "before the program starts" means before `main` starts running. – Joseph Mansfield Jan 11 '15 at 10:38
  • @JosephMansfield: I think we have two terminologies here indeed. The OS one, and the C++ one. On the OS level, the program starts, including runtime-turing complete static initialization, well before `main`. Within the C++ standard, `main` is indeed the starting point of the program ("A program shall contain a global function called main, which is the designated start of the program"). I can't help, but the OS one is more precise and correct, but I realise I opened up a barrell unecessarily; but your edit was nice. – Sebastian Mach Jan 11 '15 at 10:45
0

You can only initialize things once, but constructors can potentially run many times. Furthermore, you should not access things that are not initialized.

Suppose this is allowed. Then you have to answer difficult questions about code like this:

int foo::static_member;
foo::foo() : static_member(42){}
foo::foo(int a) : static_member(a) {}
foo::foo(double b) {}

int main()
{
  std::cout << foo::static_member;
  foo m(2.5);
}

Does it make sense? Which parts of the language do you have to change for it to make sense and not be dangerously confusing? Which benefits from allowing this kind of code outweigh added confusion and complexity? The answers would be, in order: nope, too many to bother, none at all.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243