C++中的初始化

初始化的概念

初始化(initialized):当对象在创建时获得了一个特定的值,称为对这个对象的初始化。

初始化后值未定义的情况有2种:

  1. 定义在函数内部的未被显示初始化的内置类型对象;
  2. 未被显示初始化的动态分配的内置类型对象。

注:内置类型,就是int、double等C++内置的类型。另,string不是内置类型,string定义的变量默认为空

其他相关概念:类内初始值构造函数初始值列表

构造函数函数体内变量的操作赋值,不是初始化。

  初始化的含义是创建变量赋予其一个初始值,而赋值的含义是把当前值擦除,而以一个新值来替代。

struct Sales_data {
	Sales_data() = default;
	Sales_data(const std::string &s): bookNo(s) {}  //冒号后为构造函数初始值列表

	std::string bookNo;
	unsigned units_sold = 0; // 类内初始值
	double revenue = 0.0; // 类内初始值
};

初始化的分类

对象初始化可以分为直接初始化、拷贝初始化、默认初始化、值初始化、列表初始化。直接初始化和拷贝初始化是通过构造函数和拷贝构造函数实现的。
string str1(10,'9');//直接初始化,没有=号
string str2(str1);//直接初始化,没有=号
string str3 = str1;//拷贝初始化,使用=号

string *ps = new string;//类类型使用默认构造函数,默认初始化为空string
string *ps2 = new string();//值初始化为空string

int *pi1 = new int;//默认初始化,值未定义
int *pi2 = new int();//值初始化,为0 

int a{0}, b = {0};//列表初始化。带花括号{}
1,直接初始化
不使用等号则使用的是直接初始化。
string str1(10,'9');//直接初始化
string str2(str1);//直接初始化
string str3 = str1;//拷贝初始化
2,拷贝初始化
使用等号(=)初始化一个变量,实际上执行的是拷贝初始化。

拷贝初始化不仅在我们使用=定义变量时会发生,在下列情况也会发生:

  • 将一个对象作为实参传递给一个非引用类型的形参。
  • 从一个返回类型为非引用类型的函数返回一个对象。
3,默认初始化
如果定义变量时没有指定初值,则变量被默认初始化。

  默认值到底是什么由变量类型决定,同时定义变量的位置也会对此有影响。如果是内置类型的变量未被显示初始化,它的值由定义的位置决定。

  定义在任何函数体之外的变量被初始化为0。

  定义在函数体内部内置类型变量不被初始化,一个未被初始化的内置类型变量时未定义的。static的除外,static的变量会执行值初始化,值为0。

  默认情况下,动态分配的对象也是默认初始化的,这意味着内置类型或组合类型的对象的值将是未定义的。而类类型对象将使用默认构造函数进行初始化:

int *pi = new int;//pi指向一个动态分配的,未初始化的无名对象
string *ps = new string;//默认初始化为空string
4,值初始化

只提供vector对象容纳的元素数量而去忽略元素的初始值,此时库会创建一个值初始化的元素初值,并把它赋予容器中的所有元素。

vector<int> v1(10);//值初始化。10个元素,每个元素的初始化为0
vector<string> v2(10);//值初始化。10个元素,每个元素都为空
vector<int> v3{10};//列表初始化。v2有1个元素,该元素的值是10
vector<int> v4(10, 1);//直接初始化。v3有10个元素,每个的值都是1
vector<int> v5{10, 1};//列表初始化。v4有2个元素,值分别是10和1

使用new动态分配和初始化对象
我们可以使用直接初始化方式来初始化一个动态分配的对象:

int *pi = new int(1024);//pi指向的对象的值为1024
string *ps = new string(10,'9');//*ps为"9999999999"

也可以对动态分配的对象进行值初始化,只需要在类型名后跟一对空括号即可:

string *ps1 = new string;//默认初始化为空string
string *ps2 = new string();//值初始化为空string
int *pi1 = new int;//默认初始化
int *pi2 = new int();//值初始化为0 
5,列表初始化(C++11新标准)

使用花括号{}为对象赋初值,称为列表初始化。当用于内置类型的变量时,这种初始化形式有一个重要特点:如果使用列表初始化且初始值存在丢失信息的风险,编译器会报错

long double ld = 3.1415926536;
int a{ld}, b = {ld}; //列表初始化。错误:转换未执行,因存在丢失信息的危险
int c(ld);	// 直接初始化。正确:转换执行,且丢失部分值
int d = ld;	// 拷贝初始化。正确:转换执行,且丢失部分值

注:
上述内容参考自C++ Primer(第5版)以及该博客https://blog.csdn.net/yang20141109/article/details/50374696

  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值