40

Below is a code snippet which could be compiled and run without error in vs2015

#include<iostream>
using namespace std;

class A {
    public:
        A(int b) :k(b) {}//second time
    const int k = 666;//first time
};

int main() {
    A a(555);
    cout << a.k << endl;
    return 0;
}

The output is 555. But as far as I know,const object should be initialized only once,after which the value is unmodifiable.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
choxsword
  • 3,187
  • 18
  • 44
  • Possible duplicate of [Has the new C++11 member initialization feature at declaration made initialization lists obsolete?](https://stackoverflow.com/questions/24149924/has-the-new-c11-member-initialization-feature-at-declaration-made-initializati) – dfrib May 03 '18 at 20:45

2 Answers2

65

It's not initialized twice; the default member initializer is just ignored. So for A a(555);, a.k is initialized as 555.

If a member has a default member initializer and also appears in the member initialization list in a constructor, the default member initializer is ignored.

From the standard, [class.base.init]/10:

If a given non-static data member has both a default member initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member's default member initializer is ignored. [ Example: Given

struct A {
  int i = /* some integer expression with side effects */ ;
  A(int arg) : i(arg) { }
  // ...
};

the A(int) constructor will simply initialize i to the value of arg, and the side effects in i's default member initializer will not take place. — end example ]

On the other hand, given

class A {
public:
    A() {}            // k will be initialized via default member initializer, i.e. 666
    A(int b) :k(b) {} // k will be initialized via member initializer list, i.e. b

    const int k = 666;
};

then for A a;, a.k will be initialized as 666.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
8

It is initialized only once.

const int k = 666;

would be used if not provided in constructor.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • What's the advised style: putting the default value that way, or as a default parameter value in the constructor? – user1997744 May 03 '18 at 20:30
  • In the class definition. Use the constructor if it makes sense to specialize the value. – Brady Dean May 03 '18 at 23:58
  • @user1997744 Using default member initializer as the default value, especially when there're multiple constructors; using member initializer list when want to overwrite them. – songyuanyao May 04 '18 at 01:15