天天看点

C++中类构造函数初始化列表和函数内赋值区别

C++类构造函数初始化列表

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

C++类构造函数函数内赋值

构造函数函数内赋值是在函数体内将参数的值逐个赋值给类的成员变量。例

class CExample {
public:
    int a;
    float b;
    //构造函数初始化列表
    CExample(): a(0),b(8.8)
    {}
    //构造函数内部赋值
    CExample()
    {
        a=0;
        b=8.8;
    }
};
           

上面的例子中两个构造函数的结果是一样的。上面的构造函数(使用初始化列表的构造函数)显式的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化。

初始化和赋值对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以。对非内置类型成员变量,为了避免两次构造,推荐使用类构造函数初始化列表。但有的时候必须用带有初始化列表的构造函数:

1.成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。

2.const成员或引用类型的成员。因为const对象或引用类型只能初始化,不能对他们赋值。

初始化数据成员与对数据成员赋值的含义是什么?有什么区别?

首先把数据成员按类型分类并分情况说明:

1.内置数据类型,复合类型(指针,引用)

在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的

2.用户定义类型(类类型)

结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体前已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,调用构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)

请看下面这段代码

#include<iostream>
using namespace std;


class student
{
public:
	student() 
	{
	};

	student(student&s)
	{
		m_age = s.m_age;
		m_name = s.m_name;
	};

	student(int age,char* name):m_age(age),m_name(name)
	{
		
	};
	~student() {};
public:
	int m_age;
	char* m_name;
};

class MyClass
{
public:
	MyClass();
	MyClass(int a, char* p, student s);
	~MyClass();

public:
	int m_a;
	char* m_str;
	student m_student;
};

MyClass::MyClass()
{
	cout << "默认构造函数被调用" << endl;
}

//MyClass::MyClass(int a, char* p,student s)
//{
//	m_a = a;
//	m_str = p;
//	m_student.m_age = s.m_age;
//	m_student.m_name = s.m_name;
//	cout << "我是重载构造函数" << endl;
//}

MyClass::MyClass(int a, char* p,student s) :m_a(a) ,m_str(p),m_student(s)
{
	cout << "我是重载构造函数2" << endl;
}



MyClass::~MyClass()
{
}

int main()
{
	student s(20, "李四");
	MyClass obj(10, "123",s);

	return 0;
}


``
当在main函数中给对象obj初始化时,如果使用被注释的MyClass类的函数体内逐个赋值的方式则会调用student类的默认构造函数,但是如果使用MyClass类的初始化列表的方式,那么就不会调用student类的默认构造函数,如果student类有拷贝构造函数的话,他会调用student类的拷贝构造函数,这时反而初始化列表的方式效率会低一些。

##### 欢迎关注问我团队公众号:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181225105018899.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xlbl95dWVfbW9fZnU=,size_16,color_FFFFFF,t_70)
           

继续阅读