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); //触发调用复制构造函数 2.2赋值操作运算符 通过重载运算符=,达到类的对象之间可以赋值功能,简化类对象的操作 但返回值必须有this指针的指向的引用"*this" b=c; //触发调用赋值操作运算符 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.基类与派生类 原则上基类复制控制由基类的成员函数完成,派生类由派生类完成在派生类进行复制控制时,要特别注意要把从基类继承而来的成员也要初始化或者赋值,因为名称一样,它在派生类找到这个函数名称后就不会再往上查找基类的函数,这直接引发派生类函数"覆盖"了基类的同名函数,从基类往派生类产现来看,又叫做派生类的函数"重写"结果我们的选择: 只能在派生类的复制控制函数加上调用基类的复制构造函数 只能在派生类的 赋值操作符加上调用基类的赋值操作符 3.1 派生类的复制构造函数实现 //基类 class derived :public demo{ //...完整代码见上面 };
4.设计指导 在基类的复制控制:有一个"三实现"原则,复制构造函数,赋值运算符,析构函数只要出现一个,就尽量实现三个在派生类的复制控制,请直接调用基类的复制函数来实现不同的分工在派生类的析构函数只调用派生类,基类也只调用基类的
|