读《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行,我的理解是:它调用了拷贝构造函数。之后我就在网上搜索了一下拷贝构造函数的使用,于是得出如下三处使用拷贝构造函数的地方:
- 一个对象以值传递的方式传入函数体
- 一个对象以值传递的方式从函数返回
- 一个对象需要通过另外一个对象进行初始化
而拷贝构造函数三处所使用的地方,都不能说是此时代码第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”时,函数依次执行了:
- VehicleSurrogate的拷贝构造函数VehicleSurrogate(const Vehicle &v);
- Automobile的拷贝函数copy()const;
- VehicleSurrogate的“=”赋值操作符operator=(const VehicleSurrogate&v);
- Automobile的拷贝函数copy()const;
而将上面这句“parking_lot[num++]=x”换为“parking_lot[num++]=VehicleSurrogate(x)”时,执行的效果是一样的,见下图2:
图 2
至此,我们可以得出:parking_lot[num++]=x这句代码,依次执行了VehicleSurrogate的拷贝构造函数和赋值操作符。