问题十六:使用初始化列表的构造函数和使用函数体的构造函数有什么区别?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/libing_zeng/article/details/54414263

先看一段代码:

class sphere: public hitable{

    public:

        sphere() {}

       sphere(vec3 cen, float r) : center(cen), radius(r) {} //这是什么鬼???

        virtual bool hit(constray& r, float tmin, float tmax, hit_record& rec) const;

        vec3 center;

        float radius;

};

 

其中这条语句:

sphere(vec3cen, float r) : center(cen), radius(r) {}

就是使用初始化列表的构造函数

 

构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。

上面这条语句做的事情是:将center初始化为cen;将radius初始化为r。特别注意这里是初始化,不是赋值,不是赋值,不是赋值

 

其等效的使用函数体的构造函数是:(函数体中是赋值

sphere(vec3 cen, float r){

         center = cen;

         radius = r;

}

 

辣么问题来了,使用初始化列表的构造函数和使用函数体的构造函数有区别吗?答案是:有

!!!先简单说说区别:

根本区别可以归结于“初始化”和“赋值”的区别

其一,“赋值”是属于计算。所以,时序上,初始化早于赋值

其二,有些类型的变量是只能初始化,不能赋值的。比如 const和引用。

 

看看网友怎么说:

http://blog.csdn.net/zuijinhaoma8/article/details/45919125

构造函数可以分两个阶段进行:(1)初始化阶段;(2)普通计算阶段。计算阶段也就是由函数体内所有的语句组成。不管成员是否在构造函数初始化列表中显式初始化,类的数据成员初始化总是在初始化阶段进行,初始化阶段先于计算阶段。构造函数初始化列表是对类的成员做初始化,而在构造函数体内只是对类的数据成员进行了一次赋值操作。

构造函数初始化列表只是指定了成员的初始值,并没有指定初始化顺序,那么成员初始化顺序又是怎样的呢?成员的初始化顺序就是定义成员的顺序,第一个定义的成员首先被初始化,然后是第二个等等。

一、若类的数据成员是静态的(const)和引用类型,必需用初始化列表 
静态(const)的数据成员只能初始化而不能赋值,同样引用类型也是只可以被初始化,那么只有用初始化列表。 

二、构造函数体内赋值会带来额外的开销,效率会低于构造函数初始化列表 

 

展开阅读全文

没有更多推荐了,返回首页