理解何时执行哪个构造函数和复制控制成员

来源:互联网 发布:淘宝店铺公告在哪 编辑:程序博客网 时间:2024/05/04 22:51

C++ Primer第四版
习题13.14 理解复制控制成员和构造函数的一个良好方式是定义一个简单的类,该类具有这些成员,每个成员打印自己的名字:
struct Exmpl {
   Exmpl() {std::cout << "Exmpl ()" << std::endl;}
   Exmpl(const Exmpl&)
   { std::cout << "Exmpl(const Exmpl&)" << std::endl;}
   //...
};
编写一个像Exmpl这样的类,给出复制控制成员和其他构造函数。然后写一个程序,用不同方式使用Exmpl类型对象:作为非引用形参传递,动态分配,放在容器中,等等。研究何时执行哪个构造函数和复制控制成员,可以帮助你融会贯通地理解这些概念。

解答:
定义Exmpl类,该类给出复制控制成员和一个默认构造函数,各成员函数输出自己的名字。主程序中以不同方式使用Exmpl类型的对象:作为非引用形参和引用形参传递,动态分配:作为函数返回值,进行赋值操作;作为元素放在vector容器中,以此研究构造函数和复制控制成员的执行情况。

程序代码如下:
//定义Exmpl类,该类给出复制控制成员和其他构造函数。
//用不同方式使用Exmpl类型对象:
//作为非引用形参和引用形参传递,动态分配,
//作为函数返回值,进行赋值操作,作为元素放在vector容器中。
//研究何时执行哪个构造函数和复制控制成员
#include <vector>
#include <iostream>

struct Exmpl {
//默认构造函数
Exmpl() { std::cout << "Exmpl()" <<std::endl;}
//复制构造函数
Exmpl(const Exmpl&)
{ std::cout << "Exmpl(const Exmpl&)" <<std::endl;}
//赋值操作符
Exmpl& operator = (const Exmpl &rhe)
{
     std::cout << "operator = (const Exmpl&)" <<std::endl;
     return *this;
}
//析构函数
~Exmpl()
{ std::cout << "~Exmpl()" << std::endl; }
};

void func1(Exmpl obj) //形参为Exmpl对象
{
}

void func2(Exmpl& obj) //形参为Exmpl对象的引用
{
}

Exmpl func3()
{
Exmpl obj;
return obj; //返回Exmpl对象
}

int main()
{
Exmpl eobj; //调用默认构造函数创建Exmpl对象eobj
func1(eobj); //调用复制构造函数
                       //调用形参Exmpl对象创建为实参Exmpl对象的副本
                      //调用执行完毕后调用析构函数撤销形参Exmpl对象
func2(eobj); //形参为Exmpl对象的引用,无需调用复制构造函数传递实参
eobj = func3(); //调用默认构造函数创建局部Exmpl对象
                           //函数返回时调用复制构造函数创建作为返回值副本的Exmpl对象
                         //然后调用析构函数撤销局部Exmpl对象
                         //然后调用赋值操作符,
                         //执行完赋值操作后,调用析构函数撤销作为返回值副本的Exmpl对象
Exmpl *p = new Exmpl; //调用默认构造函数动态创建Exmpl对象
std::vector<Exmpl> evec(3); //调用默认构造函数
                                               //创建一个临时值Exmpl对象
                                               //然后3次调用复制构造函数,
                                              //将临时值Exmpl对象复制到vector容器evec的每个元素
                                               //然后调用析构函数撤销临时值Exmpl对象
delete p; //调用析构函数撤销动态创建的Exmpl对象
return 0; //evec及eobj生命期结束,自动调用析构函数撤销
                   //撤销evec需调用析构函数3次(因为evec有3个元素)
}

运行该程序得到如下输出结果:
Exmpl()
Exmpl(const Exmpl&)
~Exmpl()
Exmpl()
Exmpl(const Exmpl&)
~Exmpl()
operator = (const Exmpl&)
~Exmpl()
Exmpl()
Exmpl()
Exmpl(const Exmpl&)
Exmpl(const Exmpl&)
Exmpl(const Exmpl&)
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()
~Exmpl()

原创粉丝点击