1.为什么要初始化?
例如int x;
此时并没有给x进行初始化,但是可能会被赋处置0
但是在更多的情况下,x
内存的是脏数据,并不清楚具体的值,所以操作未知的值会引发意想不到的状况,为此,我们使用对象前需要进行初始化。
2.基础知识:C++的内置类型(C++不保证初始化内置类型,会初始化非内置类型)
类型 | 描述 | 大小(字节) | 范围 |
---|---|---|---|
bool | 布尔类型 | 1 | true/false |
char | 字符类型 | 1 | -128 到 127 或 0 到 255 |
signed char | 有符号字符类型 | 1 | -128 到 127 |
unsigned char | 无符号字符类型 | 1 | 0 到 255 |
short | 短整数类型 | 2 | -32768 到 32767 |
unsigned short | 无符号短整数类型 | 2 | 0 到 65535 |
int | 整数类型 | 4 | -2147483648 到 2147483647 |
unsigned int | 无符号整数类型 | 4 | 0 到 4294967295 |
long | 长整数类型 | 4 或 8 | -2147483648 到 2147483647 或更大 |
unsigned long | 无符号长整数类型 | 4 或 8 | 0 到 4294967295 或更大 |
long long | 长长整数类型 | 8 | -9223372036854775808 到 9223372036854775807 |
unsigned long long | 无符号长长整数类型 | 8 | 0 到 18446744073709551615 |
float | 单精度浮点数类型 | 4 | 精度约为6位小数 |
double | 双精度浮点数类型 | 8 | 精度约为15位小数 |
long double | 长双精度浮点数类型 | 8 或 16 | 精度约为15位小数或更大 |
wchar_t | 宽字符类型 | 2 或 4 | 1 个宽字符编码单元(UTF-16)或代码点(UTF-32) |
char16_t | UTF-16字符类型 | 2 | 1 个UTF-16代码单元 |
char32_t | UTF-32字符类型 | 4 | 1 个UTF-32代码单元 |
void | 空类型 | 无 | 无法存储值 |
std::nullptr_t | 指针 |
3.推荐的初始化方式
·首先看不推荐的初始化方式(记住C++规定对象的成员变量初始化动作发生在进入构造函数本体之前)
class Student //首先定义一个类
{
public:
Student(int age,int number,string name);
private:
int s_age;
int s_number;
string s_name;
}
Student:Student(int age,int number,string name) //构造函数的实现
{
s_age=age; //这是使用赋值的方式,而非初始化的方式,因为在构造函数体内
s_number=number;
s_name=name;
}
以下是推荐的方式:使用初始化列表
class Student //首先定义一个类
{
public:
Student(int age,int number,string name);
private:
int s_age;
int s_number;
string s_name;
}
Student:Student(int age,int number,string name) //构造函数的实现
:s_age(age),s_number(number),s_name(name) //这才是真正的初始化,而不是赋值
{
}
·二者的区别和联系以及优缺点
首先两段代码在使用上几乎没有区别,但是在时间效率上有所不同。第一种方式(在构造函数函数体内进行初始化),这种方式,首先Student
这个构造函数对s_age s_number s_name
进行了设初值,然后显式的对s_age s_number s_name
进行赋值,所以浪费了Student
构造函数做的事。
第二种方式只使用了一次拷贝构造函数对s_age s_number s_name
进行了初始化,效率会有很大的提高。
虽然对于内置类型,两种方式的效率几乎相同,但是为了统一,建议还是都使用初始化列表的方式进行初始化。
4.初始化列表部分初始化
如果只想初始化几个成员变量,而不想全部初始化,可以使用以下做法:
Student:Student() //使用无参构造函数
:s_age(18),s_number(2012),s_name() //只对s_age和s_number进行了初始化,对于非内置类型s_name此时没有初始化,则有构造函数进行初始化
{ //虽然没有全部进行初始化,但是还是得写在初始化列表以免遗漏
}
5.一定使用初始化的方式情况:
当有const和引用时候,就不可以使用赋值的方式。
6.注意事项
成员变量的声明顺序可以不和初始化列表写的顺序相同,但是实际上初始化顺序还是按照声明顺序进行的,不过请按照声明顺序书写初始化列表。