问题描述
class A {public: int _a = 2; //直接赋值 A(){}}
什么情况下应该这样赋值,什么情况下应该在构造函数里赋值?
问题解答
回答1:class A {public: int _a = 2; // 类内初始化 A(){}}
这样的写法与
class A {public: int _a; A() : _a(2) {} // 构造函数初始化列表}
效果相同,赋初值的过程都会发生在构造函数的成员初始化阶段,前者只是 C++11 增加的语法糖。这样如果类有多个构造函数的时候,如果一个成员的初值在这些构造函数中相同,那么就可以通过类内初始化的方式设置初值,减少重复劳动。
回答2:就地初始化(“直接赋值”)比较好,简洁明了
回答3:我猜你应该是想在每一个类初始化的时候就把_a赋值为2吧?这种情况就把int _a = 2写到A的默认构造函数里面好了。
A(){_a = 2;}
还是说你想多个类的实例共享一个_a变量?这种情况你应该用static关键字
static int _a;
还要注意一下访问权限
回答4:就地初始化这个比较方便的是可以直接在声明的时候使用type var=?或者type var{}赋值,可以摆脱一个为了初始化而写构造函数的麻烦,不过这需要最新的c++11标准才行,相对于初始化列表,不用再为了摆脱编译器的初始化与声明顺序不一致的警告(这有时候其实是非常危险的)调整变量在初始化列表中的顺序。
struct Init{ int x = 11; int z {10};};初始化列表
初始化列表是一种非常“古老”的初始化方式,相对于就地初始化优势也很明显,并不需要什么新特性支持,c++所有版本都能支持,还有一个好处就是可以用来委托构造(c++11)。
struct InitList{ InitList():InitList(10, 11) {}InitList(int x, int z):x(x),z(z) {}int x; int z;};
至于用什么是属于个人习惯的问题,初始化列表更通用一些,当前也可以结合两者一起使用。
注意:当一个成员在初始化列表和就地初始化同时存在时,初始化列表优先执行,就地初始化会被忽略。
回答5:类内初始值会被转写进构造函数里所以并没有任何区别由于写了类内初始值的成员的初始化顺序依然会按默认顺序,所以我推荐不写类内初始值