类成员的快速初始化
类成员的快速初始化
苏丙榅1. C++98 标准的类成员初始化
在C++98中,支持了在类声明中使用等号 = 加初始值 的方式,来初始化类中静态成员常量 。这种声明方式我们也称之为”就地”声明。而非静态成员变量的初始化则必须在构造函数中进行。
下面通过一段代码来举例说明:
1 | struct Base |
第7行:类的非静态成员,必须在构造函数中进行初始化
第8行:类的静态成员,必须在类的外部进行初始化
第9行:类的静态常量成员,
但不是整形或者枚举,无法通过编译
如果使用 g++ 可能发现就地初始化 double 类型的静态常量是可以通过编译的,不过这实际是 GNU 对C++的一个扩展,并不遵从C++ 标准。
第10行:类的静态常量成员,
但不是整形或者枚举,无法通过编译
第8、9、10行的变量初始化方式是一样的,都是在类的外部
1
2
3int Base::c = 110;
const double Base::d = 3.14;
const char* const Base::e = "i am luffy";
答疑解惑:上面程序中的 static const 和 const static 是等价的。
2. C++11 标准的类成员初始化
2.1 初始化类的非静态成员
在进行类成员变量初始化的时候,C++11标准对于C++98做了补充,允许在定义类的时候在类内部直接对非静态成员变量进行初始化,在初始化的时候可以使用等号 = 也可以使用花括号 {} 。
1 | class Test |
可以看到如果使用花括号 {}
的方式对类的非静态成员进行初始化,等号是可以省略不写的。
- 第9行:错误,不能使用小括号() 初始化对象,应该使用花括号{}
2.2 类内部赋值和初始化列表
在C++11之前对于非静态的类成员变量我们除了在构造函数内部进行赋值,也可以在类的初始化列表中进行初始化(这种方式比在构造函数内部赋值效率高)。那么,如果同时在类内部对非静态成员变量就地初始化和在初始化列表中进行初始化会怎么样呢?下面来测试一下:
1 | class Init |
- 第4行:使用初始化列表对类的非静态成员进行初始化
- 第6、7、8行:在类内部对非静态成员变量就地初始化(C++11新特性)
执行程序,输出的结果如下:
1 | a: 10, b: 20, c: 30 |
我们可以从函数的打印输出中看到,在类内部就地初始化和初始化列表并不冲突(程序可以正常运行)。程序员可以为同一成员变量既在类内部就地初始化,又在初始化列表中进行初始化,只不过初始化列表总是看起来后作用于
非静态成员。也就是说,通过初始化列表指定的值会覆盖就地初始化时指定的值。