1.前言 復(fù)制控制通常指類的復(fù)制構(gòu)造函數(shù),賦值操作運(yùn)算符,析構(gòu)函數(shù) 1.1復(fù)制構(gòu)造函數(shù) 引入復(fù)制構(gòu)造函數(shù)是為了讓類的對象直接生成另一個(gè)對象,同時(shí)把此對象的數(shù)據(jù)復(fù)制到另一個(gè)對象中 如果類中沒有實(shí)現(xiàn)復(fù)制構(gòu)造函數(shù),編譯器自動(dòng)添加一個(gè), 如果我們不需要,則把它明確的禁止,禁止方法是在private聲明一個(gè) 2.定義 2.1復(fù)制構(gòu)造函數(shù)的2種方法實(shí)現(xiàn) base(const base& org):x(org.x),y(org.y){} //用初始化列表方式實(shí)現(xiàn) base(const base& org){x=org.x; y=org.y;} //用傳統(tǒng)函數(shù)方式初始化成員 復(fù)制構(gòu)造函數(shù)沒有返回值,是一種特別的構(gòu)造函數(shù),自動(dòng)可以用構(gòu)造函數(shù)的初始化列表達(dá)式 demo c(b); //觸發(fā)調(diào)用復(fù)制構(gòu)造函數(shù) 2.2賦值操作運(yùn)算符 通過重載運(yùn)算符=,達(dá)到類的對象之間可以賦值功能,簡化類對象的操作 但返回值必須有this指針的指向的引用"*this" b=c; //觸發(fā)調(diào)用賦值操作運(yùn)算符 2.3代碼例子: #include <iostream> class demo{ public: demo():x(0),y(0){}//無參數(shù)的構(gòu)造函數(shù) demo(int a1,int b1):x(a1),y(b1){}//有默認(rèn)值參數(shù)的構(gòu)造函數(shù) void setxy(int a=0,int b=0){x=a; y=b;} //修改x,y成員 void print(){std::cout<<" x="<<x<<" y="<<y<<"\n";} //3個(gè)復(fù)制控制函數(shù)在一起實(shí)現(xiàn) demo(const demo& org):x(org.x),y(org.y){} //復(fù)制構(gòu)造函數(shù) demo& demo::operator=(const demo& rhs){x=rhs.x; y=rhs.y; return *this;} //賦值操作運(yùn)算符 ~demo(){}//析構(gòu)函數(shù) protected: int x; int y; }; class derived :public demo{ public: //派生類構(gòu)造函數(shù) derived():demo(),z(0){}//無參數(shù)的構(gòu)造函數(shù) derived(int a2,int b2,int c2):demo(a2,b2),z(c2){}//有默認(rèn)值參數(shù)的構(gòu)造函數(shù) //重寫print() void print(){std::cout<<" x="<<x<<" y="<<y<<" z="<<z<<"\n";} //派生類復(fù)制控制(復(fù)制構(gòu)造函數(shù),賦值運(yùn)算符,析構(gòu)函數(shù)) derived(const derived& org):demo(org),z(org.z){} //復(fù)制構(gòu)造函數(shù) derived& derived::operator=(const derived& rhs)//賦值操作運(yùn)算符 { if (this!=&rhs){ demo::operator=(rhs); //調(diào)用基類的=運(yùn)算 z=rhs.z; } return *this; } ~derived(){}//析構(gòu)函數(shù) private: int z; }; int main(){ //基類調(diào)用 std::cout<<"base class demo\n"; demo b; //此時(shí)b的x,y都為0 b.print(); b.setxy(5,22); //此時(shí)b的x變 b.print(); //調(diào)用復(fù)制構(gòu)造函數(shù)用B的數(shù)據(jù)直接去初始化 demo c(b); //對象c的x,y由原來的0變成5,22 c.print(); c.setxy(10,100);//修改c對象的x,y分別為10,100 //調(diào)用賦值操作運(yùn)算符 b=c; //用c的成員值直接賦值到b對象的所有成員 c.print(); std::cout<<"derived class demo\n"; //派生類調(diào)用 derived d1(11,22,33),d2; d1.print(); d2.print(); d2=d1; d2.print(); d2.setxy(2,8); d2.print(); derived d3(d2); d3.print(); return 0; } //以上代碼用dev-c++測試通過 3.基類與派生類 原則上基類復(fù)制控制由基類的成員函數(shù)完成,派生類由派生類完成在派生類進(jìn)行復(fù)制控制時(shí),要特別注意要把從基類繼承而來的成員也要初始化或者賦值,因?yàn)槊Q一樣,它在派生類找到這個(gè)函數(shù)名稱后就不會再往上查找基類的函數(shù),這直接引發(fā)派生類函數(shù)"覆蓋"了基類的同名函數(shù),從基類往派生類產(chǎn)現(xiàn)來看,又叫做派生類的函數(shù)"重寫"結(jié)果我們的選擇: 只能在派生類的復(fù)制控制函數(shù)加上調(diào)用基類的復(fù)制構(gòu)造函數(shù) 只能在派生類的 賦值操作符加上調(diào)用基類的賦值操作符 3.1 派生類的復(fù)制構(gòu)造函數(shù)實(shí)現(xiàn) //基類 class derived :public demo{ //...完整代碼見上面 };
4.設(shè)計(jì)指導(dǎo) 在基類的復(fù)制控制:有一個(gè)"三實(shí)現(xiàn)"原則,復(fù)制構(gòu)造函數(shù),賦值運(yùn)算符,析構(gòu)函數(shù)只要出現(xiàn)一個(gè),就盡量實(shí)現(xiàn)三個(gè)在派生類的復(fù)制控制,請直接調(diào)用基類的復(fù)制函數(shù)來實(shí)現(xiàn)不同的分工在派生類的析構(gòu)函數(shù)只調(diào)用派生類,基類也只調(diào)用基類的
|