13.理解复制控制成员和构造函数的一个良好方式是定义一个简单类,该类具有这些成员,每个成员打印自己的名字:
struct Exmp1 {
Exmp1()
{ std::cout << “Exmp1()” << std::endl; }
Exmp1( const Exmp1& )
{ std::cout << “Exmp1( const Exmp1& )” << std::endl; } // …
};
编写一个像Exmp1这样的类,给出复制控制成员和其他构造函数。然后写一个程序,用不同方式使用Exmp1类型的对象:作为非引用和引用形参传递,动态分配,放在容器中,等等,研究何时执行哪个构造函数和复制控制成员,可以帮助你融会贯通第理解这些概念。
#include "stdafx.h"
#include<iostream>
#include<vector>
using namespace std;
class Exmp1{
public:
Exmp1()//默认构造函数
{std::cout << "Exmp1()" << std::endl;}
Exmp1(const Exmp1& )//复制构造函数
{std::cout << "Exmp1(const Exmp1&)" << std::endl;}
Exmp1& operator = (const Exmp1 &rhe)//赋值操作符
{
std::cout << "operator = (const Exmp1&)" <<std::endl;
return *this;
}
~Exmp1()//析构函数
{std::cout << "~Exmp1()" << std::endl;}
};
void func1(Exmp1 obj)//形参为Exmp1对象
{
}
void func2(Exmp1 &obj)//形参为Exmp1对象的引用
{
}
Exmp1 func3()//形参为Exmp1对象
{
Exmp1 obj;
return obj;
}
int main()
{
cout << "Exmp1 eobj" << endl;
Exmp1 eobj;//调用默认构造函数创建类对象eobj
cout << endl;
cout << "func1(eobj);" << endl;
func1(eobj);//复制构造函数第一种情况,
//调用复制构造函数把一个对象显示初始化另一个对象
//函数执行完毕后调用析构函数撤销形参Exmp1对象
cout << endl;
cout << "func2(eobj);" << endl;
func2(eobj);//形参为eobj的引用,无须调用复制构造函数传递实参
cout << endl;
cout << "eobj = func3();" << endl;
eobj = func3();//第二三种情况,作为函数实参,和从函数返回时复制一个对象
//1.调用默认构造函数创建局部Exmp1对象,Exmp1 obj;
//2.函数返回时调用复制构造函数创建副本的类对象Exmp1 func3
//3.调用析构函数撤销局部类对象
//4.调用赋值操作符
//5.调用析构函数撤销func3()返回值副本的类对象
cout << endl;
cout << "Exmp1 *p = new Exmp1" << endl;
Exmp1 *p = new Exmp1;//调用默认构造函数动态创建新对象
std::vector<Exmp1>evec(3);//调用默认构造函数,创建一个临时对象
//3次调用复制构造函数,将临时对象复制到容器的每个元素
//调用析构函数撤销临时对象
delete p;//调用析构函数撤销动态创建的对象
system("pause");
return 0;//evec eobj生命结束,自动调用析构函数撤销
//撤销evec徐调用析构函数3次(有三个元素)
}