C++Primer学习之四初始化

本文深入探讨了C++中初始化的多种方式,包括默认初始化、拷贝初始化、直接初始化、列表初始化以及特殊情况下如数组初始化、类内初始化等。详细解释了每种初始化类型的特点和用法,并通过实例演示如何在实际编程中应用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.默认初始化

调用无参或者时提供了默认参数的构造函数。

.拷贝初始化

A a;
A b = a;
A c = 3; // 默认class A有一个形参为int的构造函数。先将3隐式转换为A,然后调用复制构造函数。

.直接初始化

我的理解:使用非复制构造且提供初始值作为构造函数实参的初始化。

.列表初始化

int a{0}, b = {0}; // 正确
double a = 3.14;
int c = {a}, d{a}; // 错误,存在信息丢失的风险,C++Primer原话。用g++测试发现只是给出一个警告,而在聚合类初始化时,发生类型丢失根本没有错误且没有警告
//原因:只有常量在编译时期才会被<span style="color:#FF0000;">评估求值</span>,所以声明a为constexpr变量时,编译才是出错。注意,const也不行。
int c = {3.14}; // g++测试编译出错,同样适用于聚合类。


单个对象的初始化

如:聚合类(所有成员都是public、没有定义任何构造函数、没有类内初始值、没有基类也没有virtual函数):关系到C++对象模型。

class/struct A
{
public:
int a;
int b;
int c;
};
A get()
{
return {1,2,3};

}


数组或者模板形式的多个元素的初始化

:vector

vector<int> ivec = {0,1,2,3,4};
vector<string> svec = {“asa”, “qqw”, “rtert”};
vector<string> svec = {10}; // 10个默认初始化的元素
vector<string> svec2 = {10, “asda”}; //10个值为“asda”的元素


④在构造函数冒号后面的初始化也属于列表初始化

应当注意,在构造函数里初始化和列表初始化在效率方面有所区别,详细参考《深度探索C++对象模型》。


.值初始化

如:

在初始化数组时,提供的初始值数少于数组长度,剩余的提供默认初始化。

不使用初始值定义局部静态变量。

vector模板中之提供元素个数不提供初始值,则元素进行的默认初始化也叫值初始化。

int *p = new int();
string *ps = new string();

int *p = new int; // default constructor

对于定义了自己的默认构造函数的类,要求值初始化是没意义的,它最终都是通过默认构造函数来初始化;对于内置类型,值初始化有着良好定义的值,而默认初始化的对象的值是未定义的。



所以,在涉及类的情况,类必须提供默认构造函数以便上述情况发生。

.类内初始值

如:

class A
{
const int a = 3;
static constexpr double b = 10.0;
};


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值