首页 > 代码库 > [技术]浅谈初始化语义与赋值语义

[技术]浅谈初始化语义与赋值语义

背景

博主是一个常年使用初始化语义的coder= =,所以经常会遇到这样的对话

int tmp(0);

XXX:诶,你这tmp函数是干什么的啊

博主:蛤?我哪里定义了tmp函数了

XXX:那你这个是什么啊

博主:初始化啊,跟你打这个鬼东西是一样的啊

int tmp=0;

XXX:蛤蛤蛤?

然后两人都陷入了茫然状态= =

基本介绍

观察这两行代码

string tmp1("2333");string tmp2="666";

有什么区别呢(不要说一个打的丑,一个打的优美)

显然,根据刚才的对话,第一行是初始化语义,第二行是赋值语义

首先,引一下度娘:

初始化在计算机编程领域中指为数据对象或变量赋初值的做法,如何初始化则取决于所用的程序语言以及所要初始化的对象的存储类型等属性。用于进行初始化的程序结构则称为初始化器或初始化列表。初始化和变量声明是有明显区别的,而且初始化也先于变量声明进行,但两者在实践中仍常被混淆。

将某一数值赋给某个变量的过程,称为赋值。

也就是说,在第一行的代码中,我们在声明变量的时候,已经在初始化列表中为其初始化了一个值(比如tmp1,它在声明时就已经是"2333"了),但在第二行的代码中,我们已经声明了变量,申请了内存,有了一个初始化的值(这决定于你声明该变量的位置,是在堆里还是在栈里),然后,你再用"666"给tmp2赋值

这个区别就很显然了

使用

继续看代码

struct a{    int data,id;    a(int d=0,int i=0):data(d),id(i){}};

 

看a的定义,我们提供了一个构造函数a::a(),当我们这样定义一个结构a的变量时,我们得到了一个data和id都为0的变量tmp

a tmp;

我们自然也可以给它赋上值,比如:

int data(2333),id(666);a tmp(data,id);

这样,我们就得到了一个data为2333,id为666的结构体变量tmp

但是,显然我们有另一种写法:

struct a{    int data,id;    a(int d=0,int i=0){        data=d,id=i;    }};

这样,我们再运行这段初始化代码,得到的结果是一样的

所以,我们为什么要使用初始化语义呢?

为什么使用初始化语义

这涉及到了两种语义的开销问题

我们在使用赋值语义时,在构造函数中,是对数据成员进行赋值,不是初始化,而数据成员会先调用默认构造函数,再调用赋值构造函数,(其实上例是不太恰当的,因为int是内置类型,如果使用一个类作为数据成员,比如string类,效果会更加明显),这样的开销显然要大一些。

而初始化语义则会调用复制构造函数(又称为拷贝构造函数),开销会小一些。

这样,效率就会提升

(可能这对于OIer们没啥用,但是在以后编写工程时,会有一些大的类与对象,在这些对象上使用两种语义,开销的大小差距会变得明显起来)

总结

其实两种语义都是可以使用,并都能达到我们想要的效果的,但是在开销方面,初始化语义显然更胜一筹

 

(据说现在编译器会自动优化赋值语义,不知道是不是真的= =)

 

总结完毕,希望对您有用

[技术]浅谈初始化语义与赋值语义