您当前的位置: 首页 >  c++

惊鸿一博

暂无认证

  • 4浏览

    0关注

    535博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C++_CopyConstructor(副本构造器 防止指针重复释放)

惊鸿一博 发布时间:2017-03-21 00:39:30 ,浏览量:4


1.背景说明:

我们可以将一个对象赋值给一个类型与之相同的变量,编译器将生成必要的代码将 源对象 各属性的值分别赋值给 目标对象  的各成员,这种赋值行为称之为“逐位复制(copy)”,在绝大多数场合下都没有问题,但是如果某些成员是指针的话,问题就来了:对象成员进行逐位复制的结果就是:你将拥有两个一模一样的实例,而这两个副本里的同名指针将指向相同的地址!于是,当删除其中一个对象时,它所包含的指针也将被删除,若此时另外一个副本对象还在引用这个指针就会出现内存问题,导致程序崩溃。(“同时”删除两个对象,也是无效的,因为CPU是逐条指令执行的,总会有先后顺序)

2.解决方法一: 重载等号(=)操作符,新的指针使用新的的内存地址,原来的指针内存地址不变,并使用下列赋值:

Myclass obj1;

Myclass obj2;

obj1=obj2;

风险:若在创建obj2实例对象时直接初始化(Myclass obj2=obj1)则实际上编译器在编译时并不使用自定义的重载等号(=)操作符,而是去寻找副本构造器,若没有就会自行创建一个,依然会进行“逐位复制(copy)”,造成指针对象指向同一内存块!所以有了解决方法二:不让编译器自定义副本构造器,而是自定义一个副本构造器。

3.解决方法二:自定义副本构造器,在其中使用 重载等号(=)操作符

4.代码 as follows:

// CopyConstructor.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
class MyClass
{
public:
	MyClass(int *P);//主构造器 传入整型指针
	MyClass(const MyClass &rhs);//重载构造函数 副本构造器
	~MyClass();

	MyClass &operator=(const MyClass &rhs);//重载赋值操作符 返回类型依然是MyClass
	void print();
private:
	int *ptr; //私有成员变量 指针类型 
		       //验证:赋值操作时 两对象的指针类型成员 同时指向同一块地址,释放时 造成重复释放内存错误
	             //所以有了副本构造器,两对象赋值时,对指针成员 规划两块内存地址,存放同一个数值,地址释放时互不影响
};

//MyClass 成员定义
MyClass::MyClass(int *p)
{
	std::cout             
关注
打赏
1663399408
查看更多评论
0.0383s