简体   繁体   中英

why we can't initialize static variable in constructor initialization list , but we can in constructor body

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?

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++.

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; .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM