C++变量初始化为何必须重视?新手最容易踩的坑详解
一、初始化及其发展
几乎所有进行C/C++开发的人员都听说过,变量一定要初始化,特别是临时(局部)变量。不初始化的坑不踩几回,开发者不会引起重视。可对大多数开发者来说,这个坑还真是不常见。但遇到了就麻烦,不容易定位。
C++中初始化变量的方式很多,尤其是C++中存在着各种基础类型、结构体、联合体和枚举体以及类对象等。这些对象的变量初始化,看上去很复杂,其实总结起来也就几种。从早期的多种方式并存,如赋值、直接初始化以及数组的聚合初始化再到现代的列表初始化和大括号初始化。
下面分别对其进行分析说明。
二、传统初始化
在传统的C++编程中,使用小括号()进行初始化,是一种非常常见的方式。
可能对于基础类型来说,直接使用小括号进行初始化,有点不太舒服。但对于字符串、类对象等却非常普遍。
如下面的例子:
int a = 10;
int b(10);
std::string s("10");
class A{
public:
A(int a){this->a_= a;}
~A(){}
private:
int a_ = 0;
};
A a(10);
在上面的这种小括号的传统初始化中,其实对于类对象来说,有着隐式转换的风险。这个在前面分析过,一个指针类型参数的构造函数,有可能隐式转换为类对象,从而产生二次释放的风险(当然,也可以引入explicit控制)。
同时,由于一些语法上的原因,对于无参的类对象声明可能被错误的使用,导致意外的结果出现,看下面的代码:
std::string s();//是一个返回string类型的函数s std::string s;//这是一个string变量
这种问题对于新手小白来说,很有可能写出这样的代码来。
从上面的情况来看,传统对象变量的以小括号初始化的方式,有优点,也有明显的易发型的错误。所以,这就是一种不稳定状态,需要进行完善和修改,不能光靠开发者自己的小心和仔细。
三、C++新标准中的初始化
在C++11以后,引入了列表初始化,用大括号{}来进行初始化,它几乎涵盖了所有的对象的初始化,不但包括基础类型、数组、结构体和类对象等等。统一的好处就是不会再犯错。
看下面的例子:
int a{10};
std::vector v{9,8,7};
std::string s{"abc"};
A a{10};
使用大括号进行的列表初始化,等于是显式的进行了类型的控制,防止出现隐式的转换,特别是窄化转换。
典型的就是把一个double数据赋值给一个int变量。类型安全得到了管理,代码的安全性也得到了提高。
另外使用列表初始化统一了常见的初始化目标,更容易为开发者接受。比如常见的数组、结构体等。
最重要的一点就是,使用大括号的列表初始化,不会产生小括号那种歧义的问题,从而避免一些不必要的问题。
四、列表初始化的应用
列表初始化除了上面提到的一些应用外,它还可以用在很多场景下:
1、类成员变量初始化
看下面的例子:
struct Demo {
int f = 0; // C++11 起支持
std::string name{"Tom"};
};
2、构造函数的初始化列表中的初始化
看下面的例子:
class A{
public:
A(int a):a_{a}{}
~A(){}
private:
int a_ = 0;
};
3、构体的显式指定初始化
这个属于C++20的新方式,在前面也分析过,例子如下:
#include <iostream>
#include <string>
//结构体
struct Demo {
std::string name;
int age;
double score;
};
int main() {
//下面两种方式均可
Demo d1 = { .name = "tom", .age = 16, .score = 85.5 };
Demo d2{ .name = "john", .age = 17, .score = 98.5 };
std::cout << d1.name << ", " << d1.age << ", " << d1.score << std::endl;
return 0;
}
使用大括号进行统一初始化的优势首先就在于统一,不需要去处理不同对象的初始化的方式,简单方便,容易理解和维护;
另外这种机制可以有效防止变量未初始化的情况,对于开发者来说,管他有没有在构造函数中初始化,都可以直接用这种方式初始化一次。
正如前面反复说的,简单即王道。
五、总结
很多基础的技术点,要积极的跟进标准的演进,及时的在开发中应用起来。
一是可以更好的引进新标准,
另外一个就是防止旧的写法意外引入的问题,最后就是对于代码的统一风格,便于维护提供有力的支持。
特别是对于新手小白,还可以放弃老的方式,直接迈进更高的标准。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。


最新评论