随着C++的学习,发现C++中初始化问题比较复杂。故在此做一下总结:
默认初始化:如果定义变量时没有指定初值,则变量被默认初始化,此时变量被赋予了“默认值”
1、如果是内置类型的变量且未被显示初始化,它的值由位置决定。定义在任何函数体之外的变量被初始化
为0.定义在函数体内部的内置类型变量将不被初始化(当然如果是static类型,则执行值初始化,内置类型
的静态变量初始化为0);
2、每个类各自决定其初始化对象的方式。而且是否允许不经过初始化就定义对象也由类自己决定
编译器会把等号右侧的初始值拷贝到新创建的对象中去
int a = 0;
int a = {0};
string str1 = "hello";
直接初始化:如果不使用等号,则执行的是直接初始化
int a(0);
int a{0};
string str1("hello");
string str2(10, 'c');//这种情况拷贝初始化不能完成
类内初始化:为类内数据成员提供一个类内初始值
1、类内初始值用于初始化数据成员。没有初始值的成员被默认初始化
限制:类内初始值只能放在花括号里,或放在等号右边,记住不能使用圆括号
列表初始化:{}
1、当用于内置类型的变量时,如果我们使用列表初始化且初始值存在丢失的风险,则编译器报错
long double ld = 3.1415926;
int a{ld}, b = {ld};//错误:转换未执行,因为存在丢失信息的风险
2、如果提供的是初始化元素值得列表,则只能把初始值都放在花括号里进行列表初始化,而不能放在
圆括号里
值初始化(容器):通常情况下,可以只提供vector对象容纳的元素数量而略去初始值。此时库会创建一个
值初始化的元素初值,并把它赋值给容器中的所有元素。这个初始值由vector对象中的
元素决定。
1、如果vector对象的元素是内置类型,比如int,则元素初始值自动设为0.
2、如果元素是某种类类型,则元素由类默认初始化
3、
vector<int> v1(10);//v1有10个元素,每个的值都是0
vector<int> v2{10};//v2有1个元素,该元素的值是10
vector<int> v3(10, 1);//v3有10个元素,每个的值都是1
vector<int> v4{10, 1);//v4有2个元素,值分别是10和1
分析:如果用的是圆括号(),可以说提供的值是用来构造vector对象的
如果用的是花括号{},可以表述称我们想列表初始化该vector对象。如果
使用了花括号{},但提供的值又不能列表初始化,就要考虑用这样的之构造
vector对象了。
vector<string> v5("hi");错误,不能使用字符串字面值构建vector对象
1、默认初始化的智能指针中保存着一个空指针
shared_ptr<T> p1;//p1为nullptr;
2、p是shared_ptr q的拷贝,此操作会递增q中的计数器。q中的指针必须能转化为T*
shared_ptr<T>p(q);
3、使用make_shared初始化,make_shared用其参数来构造给定类型的对象。如果我们不传递任何参数,
对象就会进行值初始化
shared_ptr<string> p1 = make_shared<string>(10,'9');
默认初始化:如果定义变量时没有指定初值,则变量被默认初始化,此时变量被赋予了“默认值”
1、如果是内置类型的变量且未被显示初始化,它的值由位置决定。定义在任何函数体之外的变量被初始化
为0.定义在函数体内部的内置类型变量将不被初始化(当然如果是static类型,则执行值初始化,内置类型
的静态变量初始化为0);
2、每个类各自决定其初始化对象的方式。而且是否允许不经过初始化就定义对象也由类自己决定
int a;
拷贝初始化:(只能提供一个初始值)如果使用一个等号初始化一个变量,实际上执行的是拷贝初始化编译器会把等号右侧的初始值拷贝到新创建的对象中去
int a = 0;
int a = {0};
string str1 = "hello";
直接初始化:如果不使用等号,则执行的是直接初始化
int a(0);
int a{0};
string str1("hello");
string str2(10, 'c');//这种情况拷贝初始化不能完成
类内初始化:为类内数据成员提供一个类内初始值
1、类内初始值用于初始化数据成员。没有初始值的成员被默认初始化
限制:类内初始值只能放在花括号里,或放在等号右边,记住不能使用圆括号
列表初始化:{}
1、当用于内置类型的变量时,如果我们使用列表初始化且初始值存在丢失的风险,则编译器报错
long double ld = 3.1415926;
int a{ld}, b = {ld};//错误:转换未执行,因为存在丢失信息的风险
2、如果提供的是初始化元素值得列表,则只能把初始值都放在花括号里进行列表初始化,而不能放在
圆括号里
值初始化(容器):通常情况下,可以只提供vector对象容纳的元素数量而略去初始值。此时库会创建一个
值初始化的元素初值,并把它赋值给容器中的所有元素。这个初始值由vector对象中的
元素决定。
1、如果vector对象的元素是内置类型,比如int,则元素初始值自动设为0.
2、如果元素是某种类类型,则元素由类默认初始化
3、
vector<int> v1(10);//v1有10个元素,每个的值都是0
vector<int> v2{10};//v2有1个元素,该元素的值是10
vector<int> v3(10, 1);//v3有10个元素,每个的值都是1
vector<int> v4{10, 1);//v4有2个元素,值分别是10和1
分析:如果用的是圆括号(),可以说提供的值是用来构造vector对象的
如果用的是花括号{},可以表述称我们想列表初始化该vector对象。如果
使用了花括号{},但提供的值又不能列表初始化,就要考虑用这样的之构造
vector对象了。
vector<string> v5("hi");错误,不能使用字符串字面值构建vector对象
vector<string> v6(10, "hi");//v6有10个值为"hi"的元素
由于智能指针是C++11新出的,故在此也顺便单独列出总结一下
智能指针初始化:1、默认初始化的智能指针中保存着一个空指针
shared_ptr<T> p1;//p1为nullptr;
2、p是shared_ptr q的拷贝,此操作会递增q中的计数器。q中的指针必须能转化为T*
shared_ptr<T>p(q);
3、使用make_shared初始化,make_shared用其参数来构造给定类型的对象。如果我们不传递任何参数,
对象就会进行值初始化
shared_ptr<string> p1 = make_shared<string>(10,'9');
shared_ptr<int> p2 = make_shared<int>(0);
shared_ptr<int> 03 = make_shared<int>();//使用值初始化