构造函数与析构函数(三)---构造函数

构造函数初始化列表

1.推荐在构造函数初始化列表中进行初始化
2.构造函数的执行分为两个阶段
	2.1 初始化段
	2.2 普通计算段

对象成员及其初始化

#include <iostream>
using namespace std;

class Object
{
public:
	Object(int num) : num_(num)
	{
		cout << "Object..." << num_ << endl;
	}

	~Object()
	{
		cout << "~Object..." << num_ << endl;
	}
private:
	int num_;
};

class Container
{
public:
	Container(int obj1=0, int obj2=0) : obj1_(obj1), obj2_(obj2)
	{
		cout << "Container..." << endl;
	}

	~Container()
	{
		cout << "~Container..." << endl;
	}
private:
	Object obj1_;
	Object obj2_;
};
int main()
{
	Container c(10, 20);
	return 0;
}

在这里插入图片描述

const成员、引用成员初始化

#include <iostream>
using namespace std;

//	const成员的初始化只能在构造函数初始化列表中进行
//	引用成员的初始化也只能在构造函数初始化列表中进行
//	对象成员(对象所对应的类没有默认构造函数)的初始化也只能在构造函数初始化列表中进行
class Object
{
public:
	Object(int num=0) : num_(num),kNum_(100), refNum_(num_)
	{
		//kNum_ = 100;	// Error
		//refNum_ = num_;	// Error
		cout << "Object..." << num_ << endl;
	}

	~Object()
	{
		cout << "~Object..." << num_ << endl;
	}
private:
	int num_;
	const int kNum_;
	int& refNum_;
};

int main()
{
	Object o(10);
	return 0;
}

枚举

拷贝构造函数

1.功能:使用一个已经存在的对象来初始化一个新的同一类型的对象
2.声明:只有一个参数并且参数为该类对象的引用
3.如果类中没有说明拷贝构造函数,系统自动生成一个缺省复制构造函数,作为该类的公有成员。
#include <iostream>
#include "Test.h"
using namespace std;

int main()
{
	Test t(10);

	Test t2(t);
	Test t3 = t;	// 与Test t3(t);等价

	return 0;
}

在这里插入图片描述

拷贝构造函数调用的几种情况

1.当函数的形参是类的对象,调用函数时,进行形参与实参结合时使用。这时要在内存新建立一个局部对象,并把实参拷贝到新的对象中。理所当然调用拷贝构造函数。
2.当函数的返回值是类对象,函数执行完成返回调用时使用。这时会建立一个临时对象,再返回调用者。为什么不直接用要返回的局部对象呢?因为局部对象再离开建立它的函数时就消亡了,不可能再返回调用函数后继续生存,所以再处理这种情况时,编译系统会在调用函数的表达式中创建一个无名临时对象,该临时对象的生存周期只在函数调用处的表达式中。所谓return对象,实际上是调用拷贝构造函数把该对象的值拷入临时对象。如果返回的是变量,处理过程类似,只是不调用构造函数。
#include <iostream>
#include "Test.h"
using namespace std;

//	演示值传递
void TestFun(const Test t)
{

}

//	演示引用传递
void TestFun2(const Test& t)
{

}

//	演示返回值是类对象
Test TestFun3(const Test& t)
{
	return t;
}

int main()
{
	Test t(10);

	TestFun(t);
	cout << "11111111111111" << endl;

	TestFun2(t);
	cout << "22222222222222" << endl;

	t = TestFun3(t);
	cout << "33333333333333" << endl;

	//	不会调用=运算符,因为是初始化,不是赋值操作
	//	不会立即销毁临时对象,相当于将临时对象改名为t2;或者说临时对象被t2接管了
	
	Test t2 = TestFun3(t);
	cout << "44444444444444" << endl;
	
	//	编译报错,非常量引用只能绑定到左值??????
	/*Test& t3 = TestFun3(t);
	cout << "55555555555555" << endl;*/

	Test t4 = TestFun3(t);
	cout << "66666666666666" << endl;
	
	return 0;
}

在这里插入图片描述

//	会报错???
//	非常量引用只能绑定到左值???
Test& t3 = TestFun3(t);
cout << "55555555555555" << endl;

虽然4444 和 6666输出结果一样,但含义不一样,自己体会如下。

4444…是返回类对象时调用拷贝构造函数,初始化时t2直接接管临时对象没有调用拷贝构造函数。
6666…是返回引用时不会调用拷贝构造函数,初始化时调用拷贝构造函数。
在这里插入图片描述


#include <iostream>
#include "Test.h"
using namespace std;

//	演示值传递
void TestFun(const Test t)
{

}

//	演示引用传递
void TestFun2(const Test& t)
{

}

//	演示返回值是类对象
Test TestFun3(const Test& t)
{
	return t;
}

//	演示返回值是类对象引用
const Test& TestFun4(const Test& t)
{
	return t;
}

int main()
{
	Test t(10);

	TestFun(t);
	cout << "11111111111111" << endl;

	TestFun2(t);
	cout << "22222222222222" << endl;

	t = TestFun3(t);
	cout << "33333333333333" << endl;

	Test t2 = TestFun3(t);
	cout << "44444444444444" << endl;

	const Test& t3 = TestFun3(t);
	cout << "55555555555555" << endl;

	Test t4 = TestFun3(t);
	cout << "66666666666666" << endl;

	const Test &t5 = TestFun4(t);
	cout << "77777777777777" << endl;

	return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值