一、类成员的快速初始化
1.C++98 标准的类成员初始化
① 初始化类中的静态成员常量("就地声明"):
类声明 : 等号 = 加初始值
② 初始化类中的非静态成员变量:
初始化 : 必须在构造函数中进行
#include <iostream>
using namespace std;
/*
C++98 标准的类成员初始化
初始化类中的静态成员常量("就地声明"):
类声明 : 等号 = 加初始值
初始化类中的非静态成员变量:
必须在构造函数中进行
*/
// 按照C++98 标准来解读
class Base {
public:
int a;
int b = 1; //类的非静态成员,必须在构造函数中进行初始化
static int c = 2; //类的静态成员,必须在类的外部进行初始化
static const double d = 3.14; //类的静态常量成员,但不是整型或者枚举,无法通过编译
static const char* p = "I am Sakura";//类的静态常量成员,但不是整型或者枚举,无法通过编译
const static int e = 0;
};
int main(){
Base b;
return 0;
}
为什么static const double d = 3.14,也就是初始化double类型的静态常量可以通过编译呢?
实际是 GNU 对C++的一个扩展,并不遵从C++ 标准。
>>修正
#include <iostream>
using namespace std;
// 按照C++98 标准来解读
class Base {
public:
int a;
int b;//类的非静态成员,必须在构造函数中进行初始化
Base(){
b = 1;
}
static int c;
static const double d;
static const char* const p;
const static int e = 0;
};
//对类的静态成员,必须在类的外部进行初始化
int Base::c = 110;
const double Base::d = 3.14;
const char* const Base::p = "I am Sakura";
int main(){
Base b;
return 0;
}
>>总结:
>>类的非静态成员,必须在构造函数中进行初始化
>>类的静态成员,必须在类的外部进行初始化
2.C++11 标准的类成员初始化
2.1 初始化类的非静态成员
#include <iostream>
using namespace std;
/*
C++11 标准的类成员初始化
初始化类中的非静态成员变量:
① 允许在定义类的时在类内部直接对非静态成员变量进行初始化
② 初始化时,可以使用 等号= ,也可以使用 花括号{}
*/
class Test {
private:
int a = 1;
int b = {2};
int c{3};
double arr1[4] = {3.14,3.15,3.16,3.17};
double arr2[4] = {3.14,3.15,3.16,3.17};
string s1("heheda");//error: expected identifier before string constan
string s2{"hello,heheda!!!"};
};
int main() {
Test t;
return 0;
}
【总结】使用花括号{}对类的非静态成员初始化, 可以省略等号
string s1("heheda");发生错误,不能使用小括号()初始化对象,应使用花括号{}
2.2 类内部赋值和初始化列表
① C++11 可以对类内部的非静态成员就地初始化
#include <iostream>
using namespace std;
/*
C++11 标准的类成员初始化
2.2 类内部赋值和初始化列表
① C++11 可以对类内部的非静态成员就地初始化
*/
class Init{
public:
int a = 1;
int b = 2;
int c = 3;
};
int main() {
Init tmp;
cout << "a: " << tmp.a << ", b: " << tmp.b << ", c: " << tmp.c << endl;
return 0;
};
② 使用初始化列表对类的非静态成员进行初始化
#include <iostream>
using namespace std;
/*
C++11 标准的类成员初始化
2.2 类内部赋值和初始化列表
① C++11 可以对类内部的非静态成员就地初始化
② 使用初始化列表对类的非静态成员进行初始化
*/
class Init{
public:
Init(int x,int y,int z) : a(x),b(y),c(z) {}
int a = 1;
int b = 2;
int c = 3;
};
int main() {
Init tmp(10,20,30);
cout << "a: " << tmp.a << ", b: " << tmp.b << ", c: " << tmp.c << endl;
return 0;
};
【总结】在类内部就地初始化和初始化列表并不冲突(程序正常运行)。看起来是:通过初始化列表指定的值会覆盖就地初始化时指定的值。
学习和参考一下文章:
类成员的快速初始化 | 爱编程的大丙 (subingwen.cn)https://subingwen.cn/cpp/quick_init/