1.前言 復制控制通常指類的復制構造函數,賦值操作運算符,析構函數 1.1復制構造函數 引入復制構造函數是為了讓類的對象直接生成另一個對象,同時把此對象的數據復制到另一個對象中 如果類中沒有實現復制構造函數,編譯器自動添加一個, 如果我們不需要,則把它明確的禁止,禁止方法是在private聲明一個 2.定義 2.1復制構造函數的2種方法實現 base(const base& org):x(org.x),y(org.y){} //用初始化列表方式實現 base(const base& org){x=org.x; y=org.y;} //用傳統函數方式初始化成員 復制構造函數沒有返回值,是一種特別的構造函數,自動可以用構造函數的初始化列表達式 demo c(b); //觸發(fā)調用復制構造函數 2.2賦值操作運算符 通過重載運算符=,達到類的對象之間可以賦值功能,簡化類對象的操作 但返回值必須有this指針的指向的引用"*this" b=c; //觸發(fā)調用賦值操作運算符 2.3代碼例子: #include <iostream> class demo{ public: demo():x(0),y(0){}//無參數的構造函數 demo(int a1,int b1):x(a1),y(b1){}//有默認值參數的構造函數 void setxy(int a=0,int b=0){x=a; y=b;} //修改x,y成員 void print(){std::cout<<" x="<<x<<" y="<<y<<"\n";} //3個復制控制函數在一起實現 demo(const demo& org):x(org.x),y(org.y){} //復制構造函數 demo& demo::operator=(const demo& rhs){x=rhs.x; y=rhs.y; return *this;} //賦值操作運算符 ~demo(){}//析構函數 protected: int x; int y; }; class derived :public demo{ public: //派生類構造函數 derived():demo(),z(0){}//無參數的構造函數 derived(int a2,int b2,int c2):demo(a2,b2),z(c2){}//有默認值參數的構造函數 //重寫print() void print(){std::cout<<" x="<<x<<" y="<<y<<" z="<<z<<"\n";} //派生類復制控制(復制構造函數,賦值運算符,析構函數) derived(const derived& org):demo(org),z(org.z){} //復制構造函數 derived& derived::operator=(const derived& rhs)//賦值操作運算符 { if (this!=&rhs){ demo::operator=(rhs); //調用基類的=運算 z=rhs.z; } return *this; } ~derived(){}//析構函數 private: int z; }; int main(){ //基類調用 std::cout<<"base class demo\n"; demo b; //此時b的x,y都為0 b.print(); b.setxy(5,22); //此時b的x變 b.print(); //調用復制構造函數用B的數據直接去初始化 demo c(b); //對象c的x,y由原來的0變成5,22 c.print(); c.setxy(10,100);//修改c對象的x,y分別為10,100 //調用賦值操作運算符 b=c; //用c的成員值直接賦值到b對象的所有成員 c.print(); std::cout<<"derived class demo\n"; //派生類調用 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ā)派生類函數"覆蓋"了基類的同名函數,從基類往派生類產現來看,又叫做派生類的函數"重寫"結果我們的選擇: 只能在派生類的復制控制函數加上調用基類的復制構造函數 只能在派生類的 賦值操作符加上調用基類的賦值操作符 3.1 派生類的復制構造函數實現 //基類 class derived :public demo{ //...完整代碼見上面 };
4.設計指導 在基類的復制控制:有一個"三實現"原則,復制構造函數,賦值運算符,析構函數只要出現一個,就盡量實現三個在派生類的復制控制,請直接調用基類的復制函數來實現不同的分工在派生類的析構函數只調用派生類,基類也只調用基類的
|