首页 > 代码库 > c++第十三章 -(副本构造器)
c++第十三章 -(副本构造器)
- 逐位复制(bitwise copy):编译器将生成必要的代码把“源”对象各属性的值分别赋值给“目标”对象的对应成员的行为。对对象的地址赋值操作,于是乎,当删除一个对象时,它包含的指针也将被删除,但万一此时另一个副本(对象)还在引用这个指针,就会出问题!
- 要是程序员在当初进行对象“复制”时能够精确地表明应该复制些什么和如何赋值,那就理想了。为解决该问题,我们可以对=操作符进行重载,其中对指针进行处理:MyClass &operator= (const MyClass &rhs);该语句的意思是表明这个方法所预期的输入参数应该是一个MyClass类型的、const常量不可改变的引用,并返回一个引用,该引用指向一个MyClass类的对象。
对赋值操作符重载的Demo:
class MyClass{public: MyClass(int *p); ~MyClass(); MyClass &operator=(const MyClass &rhs); void print();private: int *ptr;};MyClass::MyClass(int *p){ ptr = p;}MyClass::~MyClass(){ delete ptr;}//MyClass a(1);MyClass(2);a = b;在这里已经对=操作符进行了重载MyClass &MyClass::operator=(const MyClass &rhs)//传入一个const常量地址{ if (this != &rhs) { delete ptr;//删除掉a对象原有的ptr成员 ptr = new int;//重新申请一块内存,表明了,现在有两个指针指向的地址是不一样滴,解决了2个指向指向同一块地址的问题 *ptr = *rhs.ptr;//将传进来对象的值赋值给ptr } else { std::cout << "赋值号两边为同个对象,不做处理!\n";// } return *this;}void MyClass::print(){ std::cout << *ptr << std::endl;}int main(int argc, const char * argv[]){ MyClass obj1(new int(1)); MyClass obj2(new int(2)); obj1.print(); obj2.print(); obj2 = obj1;//这里=号已经重载了 obj1.print(); obj2.print(); return 0;}
控制台输出结果:
1211
副本构造器何时被调用?当创建一个实例对象obj1,然后再创建实例obj2的同时用obj1的值对它进行初始化,此时,编译器将在MyClass类里寻找一个副本构造器(copy constructor),如果找不到,它会自行创建一个。即使我对之前的=操作符进行了重载,但由编译器(系统)创建的副本构造器仍以“逐位复制”的方法把obj1赋值给obj2。换句话说就是我们对=操作符进行了重载,“逐位复制”的行为仍然会发生。然而这个时候,我们就须要自定义一个副本构造器:MyClass(const MyClass &rhs);
副本构造器Demo:
class MyClass{public: MyClass(int *p); MyClass(const MyClass &rhs);//副本构造器 ~MyClass(); MyClass &operator= (const MyClass &rhs); void print();private: int *ptr;};MyClass::MyClass(int *p){ std::cout << "进入构造器\n"; ptr = p;}MyClass::MyClass(const MyClass &rhs){ std::cout << "进入副本构造器\n"; *this = rhs;//这里的=操作符已经被重载了}MyClass::~MyClass(){ std::cout << "进入析造器\n"; delete ptr;}MyClass &MyClass::operator=(const MyClass &rhs){ std::cout << "进入赋值语句重载\n"; if (this != &rhs) { delete ptr; ptr = new int; *ptr = *rhs.ptr; } else { std::cout << "赋值号两边为同个对象,不做处理!\n";// } return *this;}void MyClass::print(){ std::cout << *ptr << std::endl;}int main(int argc, const char * argv[]){ MyClass obj3(new int(3)); MyClass obj4 = obj3;// obj3.print(); obj4.print(); return 0;}
控制台输出:
进入构造器进入副本构造器进入赋值语句重载33进入析造器进入析造器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。