构造函数初始化列表和构造函数体内赋值

#include <iostream>
using namespace  std;

class A{
public:
	A(int a,string str)
	{
		m_a = a;
		m_str = str;
	}
	//A(int a,string str):m_a(a),m_str(str){}

	 void print()
	 {
		 cout << m_a << ' '<< m_str<< endl;
	 }

private:
	int m_a;
	string m_str;

};

int main(int argc, char **argv)
{
	A a(1,"hello");
	a.print();
	return 0;
}

运行结果相同,那么两者区别在哪里???

从概念上,我们可以认为构造函数分两个阶段执行:

(1)初始化阶段       (2)普通的计算阶段。

①不管成员是否在构造函数初始化列表中显式初始化, 类类型的数据成员总是会在初始化阶段初始化。 初始化发生在计算阶段开始之前。

②在构造函数初始化列表中没有显示提及的每个成员, 使用与初始化变量相同的规则来进行初始化。 运行该类型的默认构造函数,来初始化类类型的数据成员。 

③内置或复合类型的成员的初始值依赖于对象的作用域:在局部作用域中这些成员不被初始化,而在全局作用域中,它们被初始化为0。

④计算阶段由构造函数体内的所有语句构成。在计算阶段中,数据成员的设置被认为是赋值,而不是初始化。没有清楚地认识到这个区别是程序错误和低效的常见源泉。

⑤. 初始化 != 赋值.;初始化代表为变量分配内存. 变量在其定义处被编译器初始化(编译时). 在函数中, 函数参数初始化发生在函数调用时(运行时).,赋值代表"擦除对象当前值, 赋予新值". 它不承担为对象分配内存的义务.

结论:构造函数初始化列表是对类的成员做初始化,而在构造函数体内只是对类的数据成员进行了一次赋值操作。


1. 初始化列表存在的价值:

首先把数据成员按类型分类并分情况说明:
①.内置数据类型,复合类型(指针,引用)
    在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的
②.用户定义类型(类类型)
     结果上相同,但是性能上存在很大的差别。更受欢迎的实现是用成员初始化表:因为类类型的数据成员对象在进入函数体前已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,调用构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)


2. 那么什么时候需要构造函数初始化列表呢?
(1) const成员
(2) 引用类型成员
(3) 继承类中调用基类初始化构造函数, 实际上就是先构造基类对象, 必须使用初始化列表.
        以上3种情况需要在构造函数初始化列表中对数据成员进行显式初始化。因为const和引用类型成员只能初始化,不能对其进行赋值操作。

#include<iostream>
using namespace std;
class A{
public:
  A(int a,int b):m_a(a),m_b(b){}
    void print(){
        cout << m_a<<' '<< m_b << endl;
    }
    int m_a;
    int m_b;
};

class B:public A{
public:

   /* B(int a,int b,int c){
        m_a = a;
        m_b = b;
        m_c = c;
    }
    */
 //   B(int a,int b,int c):m_a(a),m_b(b),m_c(c){}
   B(int a,int b,int c):A(a,b),m_c(c){}
    void print()
    {
        cout << m_a<<' '<< m_b<< ' '<< m_c <<endl;
    }
    int m_c;

};

int main(){

    B b(1,2,3);
    b.print();
 //   A a(1,2);
  //  a.print();
   return 0;
}

事实上我们应该尽量使用初始化列表,而不要在构造函数里赋值

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



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值