• 读《C++沉思录》心得:拷贝构造函数


    读《C++沉思录》心得:拷贝构造函数

      在读《C++沉思录》中第53页的下面这段代码时,突然看不懂了:

    1 int num=0;
    2 VehicleSurrogate parking_lot[3];
    3 Automobile x;
    4 parking_lot[num++]=x;
    5 //最后一天语句等价于下句
    6 //parking_lot[num++]=VehicleSurrogate(x);

      书上是这么解释上面这段的:

    •   “这个语句创建了一个关于对象x的副本,并将VehicleProxy对象绑定到该副本,然后将这个对象赋值给parking_lot的一个元素。当最后销毁parking_lot数组时,所有这些副本也被清除。”

      对于书上的这段解释,我可以理解它是解释代码中的第6行,但是完全不能理解它可以解释第4行。对于第4行,我的理解是:它调用了拷贝构造函数。之后我就在网上搜索了一下拷贝构造函数的使用,于是得出如下三处使用拷贝构造函数的地方:

    1. 一个对象以值传递的方式传入函数体 
    2. 一个对象以值传递的方式从函数返回
    3. 一个对象需要通过另外一个对象进行初始化

      而拷贝构造函数三处所使用的地方,都不能说是此时代码第4句的这种情形。就算是那也只能说第4句它肯定调用了拷贝构造函数,并且它使用的是拷贝构造函数使用情况的第三种情况。但是那个“=”是怎么回事呢,带着这种疑惑我决定亲自写代码测试一下,看能不能发现什么。

      以下为我将《C++沉思录》中的这段代码的例子简易写下来为了测试的代码:

     //class Vehicle
    //Vehicle.h
    1
    #include<iostream> 2 using namespace std; 3 class Vehicle 4 { 5 public: 6 virtual Vehicle* copy() const=0; 7 virtual ~Vehicle() 8 { 9 cout<<"this is class Vehicle::~Vehicle()"<<endl; 10 11 } 12 };
     //class Automobile
    //Automobile.h
    1
    #include<vehicle.h> 2 #include<iostream> 3 using namespace std; 4 class Automobile : public Vehicle 5 { 6 public: 7 Automobile(); 8 Vehicle* copy() const; 9 ~Automobile(); 10 };
     //class Automobile
    //Automobile.cpp
    1
    #include "automobile.h" 2 3 Automobile::Automobile() 4 { 5 cout<<"this is class Automobile::Automobile()"<<endl; 6 } 7 8 Vehicle *Automobile::copy() const 9 { 10 cout<<"this is class Automobile::copy() const"<<endl; 11 return new Automobile(*this); 12 } 13 14 Automobile::~Automobile() 15 { 16 cout<<"this is class Automobile::~Automobile()"<<endl; 17 }
     //class VehicleSurrogate
    //VehicleSurrogate.h
    1
    #include"vehicle.h" 2 #include<iostream> 3 using namespace std; 4 class VehicleSurrogate 5 { 6 public: 7 VehicleSurrogate(); 8 VehicleSurrogate(const Vehicle& v); 9 VehicleSurrogate(const VehicleSurrogate&v); 10 VehicleSurrogate&operator=(const VehicleSurrogate&v); 11 ~VehicleSurrogate(); 12 private: 13 Vehicle *vp; 14 };
     //class VehicleSurrogate
    //VehicleSurrogate.cpp
    1
    #include "vehiclesurrogate.h" 2 3 VehicleSurrogate::VehicleSurrogate():vp(0) 4 { 5 cout<<"this is class VehicleSurrogate::VehicleSurrogate()"<<endl; 6 } 7 8 VehicleSurrogate::VehicleSurrogate(const Vehicle &v)//:vp(v.copy) 9 { 10 vp=v.copy(); 11 cout<<"this is class VehicleSurrogate::VehicleSurrogate(const Vehicle &v)"<<endl; 12 } 13 14 VehicleSurrogate::VehicleSurrogate(const VehicleSurrogate & v):vp(v.vp?v.vp->copy():0) 15 { 16 cout<<"this is class VehicleSurrogate::VehicleSurrogate(const VehicleSurrogate & v)"<<endl; 17 } 18 19 VehicleSurrogate &VehicleSurrogate::operator =(const VehicleSurrogate &v) 20 { 21 cout<<"this is class VehicleSurrogate::operator =(const VehicleSurrogate &v)"<<endl; 22 if(this!=&v) 23 { 24 delete vp; 25 vp=(v.vp?v.vp->copy():0); 26 } 27 return *this; 28 } 29 30 VehicleSurrogate::~VehicleSurrogate() 31 { 32 cout<<"this is class VehicleSurrogate::~VehicleSurrogate()"<<endl; 33 delete vp; 34 }
     //main.cpp
    1
    #include <iostream> 2 #include"vehiclesurrogate.h" 3 #include"vehicle.h" 4 #include"automobile.h" 5 using namespace std; 6 7 int main() 8 { 9 int num=0; 10 VehicleSurrogate parking_lot[3]; 11 Automobile x; 12 parking_lot[num++]=x; 13 //parking_lot[num++]=VehicleSurrogate(x); 14 15 return 0; 16 }

      通过对上面代码的运行,得出运行结果如下图1:

    图 1

      由运行结果的第5,6,7,8行可以看出,在调用“parking_lot[num++]=x”时,函数依次执行了:

    1. VehicleSurrogate的拷贝构造函数VehicleSurrogate(const Vehicle &v);
    2. Automobile的拷贝函数copy()const;
    3. VehicleSurrogate的“=”赋值操作符operator=(const VehicleSurrogate&v);
    4. Automobile的拷贝函数copy()const;

      而将上面这句“parking_lot[num++]=x”换为“parking_lot[num++]=VehicleSurrogate(x)”时,执行的效果是一样的,见下图2:

     图 2

      至此,我们可以得出:parking_lot[num++]=x这句代码,依次执行了VehicleSurrogate的拷贝构造函数和赋值操作符。

  • 相关阅读:
    例程详解
    js对数组中有相似属性对象进行合并
    javaScript放大镜特效
    css改变图标颜色
    js自定义日历
    vuecli4.0配置公共scss样式文件
    iframe根据子页面的内容来设置高度
    iframe父子页面交互
    artTemplate模板自定义函数
    javascript数组的增删改和查询
  • 原文地址:https://www.cnblogs.com/maybob/p/3081521.html
Copyright © 2020-2023  润新知