C++ 复制功能
C++ 复制功能
说C++复制功能,它可能不是很熟悉。类中的拷贝构造函数和赋值操作符。可是其实或许我们一不小心就会忽略编译器所做的一些默认操作。引起晦涩的错误。以下分析几种场景:
一、场景一:所有默认
#include<stdio.h> class base{ public: base(){} base(int dt):data(dt){} void get(){printf("base::data = %d\n",data);} public: int data; }; class derived:public base{ public: derived(){} derived(int dt,int ddt):base(dt),ddata(ddt){} void get() { base::get(); printf("derived::ddata = %d\n",ddata); } private: int ddata; }; int main() { derived da(1,5); derived db(2,10); da.get(); db.get(); da = db; da.get(); db.get(); derived dc(da); dc.get(); base ba(da); ba.get(); getchar(); }结果:
假设在编译器中执行程序,我们知道,当调用复制函数是。除了派生类的成员被复制外。基类的成员也被复制。这是编译器的行为,当用户未定义复制行为时,编译器就会主动提供一个默认版本号同一时候在须要的时候悄悄的调用完毕复制工作。
场景二、基类默认,派生类自己定义
#include<stdio.h> class base{ public: base(){} base(int dt):data(dt){} void get(){printf("base::data = %d\n",data);} public: int data; }; class derived:public base{ public: derived(){} derived(int dt,int ddt):base(dt),ddata(ddt){} derived(const derived&d) { printf("call derived::copy construct function.\n"); ddata = d.ddata; } derived& operator=(const derived&d) { printf("call derived::operator= function.\n"); ddata = d.ddata; return *this; } void get() { base::get(); printf("derived::ddata = %d\n",ddata); } private: int ddata; };结果:
从结果能够看出,当用户定义了复制函数时。一切默认行为就不会发生,即派生类中不会隐式调用基类的默认复制函数。
场景三、基类自己定义,派生类默认
#include<stdio.h> class base{ public: base(){} base(int dt):data(dt){} base(const base&b) { printf("call base::copy construct function.\n"); data = b.data; } base& operator=(const base&d) { printf("call base::operator= function.\n"); data = d.data; return *this; } void get(){printf("base::data = %d\n",data);} public: int data; }; class derived:public base{ public: derived(){} derived(int dt,int ddt):base(dt),ddata(ddt){} void get() { base::get(); printf("derived::ddata = %d\n",ddata); } private: int ddata; };结果:
从结果能够看出。当派生类没有显示定义复制函数时,那么他就会调用默认的复制函数,而默认复制函数会自己主动调用基类的复制函数。
场景四、基类派生类都自己定义
#include<stdio.h> class base{ public: base(){} base(int dt):data(dt){} base(const base&b) { printf("call base::copy construct function.\n"); data = b.data; } base& operator=(const base&d) { printf("call base::operator= function.\n"); data = d.data; return *this; } void get(){printf("base::data = %d\n",data);} public: int data; }; class derived:public base{ public: derived(){} derived(int dt,int ddt):base(dt),ddata(ddt){} derived(const derived&d):base(d) { printf("call derived::copy construct function.\n"); ddata = d.ddata; } derived& operator=(const derived&d) { printf("call derived::operator= function.\n"); ddata = d.ddata; return *this; } void get() { base::get(); printf("derived::ddata = %d\n",ddata); } private: int ddata; };
结果:
从结果看出,仅仅要定义了派生类的复制函数,那么就不会隐式调用基类的复制函数。
结论:仅仅要派生类定义了复制函数,那么就不会隐式调用基类的复制函数,所以在这样的情况下。我们必须显示调用基类的复制函数,以免造成复制的不完整。
以下给出显示调用的样例:
class base{ public: base(){} base(int dt):data(dt){} base(const base&b) { printf("call base::copy construct function.\n"); data = b.data; } base& operator=(const base&d) { printf("call base::operator= function.\n"); data = d.data; return *this; } void get(){printf("base::data = %d\n",data);} public: int data; }; class derived:public base{ public: derived(){} derived(int dt,int ddt):base(dt),ddata(ddt){} derived(const derived&d):base(d) { printf("call derived::copy construct function.\n"); ddata = d.ddata; } derived& operator=(const derived&d) { printf("call derived::operator= function.\n"); base::operator=(d); ddata = d.ddata; return *this; } void get() { base::get(); printf("derived::ddata = %d\n",ddata); } private: int ddata; };结果: