有一个类
class A
{
public:
A();
~A();
BYTE* GetData();
void SetData(BYTE* data);
void Clear();
A& operator =(A &a);
protected:
BYTE* m_pbData;
}A& A:: operator=(A &a)
{
Clear(); //这里有一个问题
SetData(a.GetData());
return *this;
}void A::Clear()
{
try
{
delete m_pbData;
}
catch(...)
{
//do nothing
}
}它的析构函数
A::~A()
{
Clear(); //这里也有一个问题
}在另一个对象中调用的时候A a = GetA();下面是GetA()的实现
A GetA()
{
A a;
BYTE *pb = new BYTE[10];
a.SetData(pb);
return a;
}在
A a = GetA();
这句执行的时候,由于在GetA()内部 return a的时候 a的析构函数被执行,所以
在赋值的时候,也就是执行重载的 = 的时候,会出错,因为m_pbData已经被delete了。关键的问题出在A::Clear()
在Clear的时候,Clear并不知道m_pbData是否被其它的对象引用,请教高手,怎样
解决这个问题?
class A
{
public:
A();
~A();
BYTE* GetData();
void SetData(BYTE* data);
void Clear();
A& operator =(A &a);
protected:
BYTE* m_pbData;
}A& A:: operator=(A &a)
{
Clear(); //这里有一个问题
SetData(a.GetData());
return *this;
}void A::Clear()
{
try
{
delete m_pbData;
}
catch(...)
{
//do nothing
}
}它的析构函数
A::~A()
{
Clear(); //这里也有一个问题
}在另一个对象中调用的时候A a = GetA();下面是GetA()的实现
A GetA()
{
A a;
BYTE *pb = new BYTE[10];
a.SetData(pb);
return a;
}在
A a = GetA();
这句执行的时候,由于在GetA()内部 return a的时候 a的析构函数被执行,所以
在赋值的时候,也就是执行重载的 = 的时候,会出错,因为m_pbData已经被delete了。关键的问题出在A::Clear()
在Clear的时候,Clear并不知道m_pbData是否被其它的对象引用,请教高手,怎样
解决这个问题?
也就是要用new操作符生成一个对象,然后返回。
如果申请的是一个变量,那么在函数执行完毕后,这个对象就不存在了。外面再次
使用时肯定是非法对象
进行引用计数,当引用计数为0时删除即可。
SetData(BYTE* data);函数要把m_pbData new出一个空间,在把data的数据拷贝到m_pbData里,这样符合逻辑否则的话析构函数就索性不要管它的删除
还有,好像你的buffer也不知道个长度,如果做深拷贝,如何进行?
出错不是因为_pbData已经被delete,而是 a 就已经不存在了,
A a;
BYTE *pb = new BYTE[10];
a.SetData(pb);
return a;
中a是一个局部变量,函数返回的时候就会被释放掉。
要返回就应该使用new在堆里生长一个新的对象。使用引用计数也应该用new生成对象,否则会造成内存泄漏
BYTE* A::GetData()
{
return m_pbData;
}另外,GetA()中的代码不应该改变,因为我需要的是这样一个对象A,而不是一个简单的内存块。此外,录GetA中的a对象释放掉之前系统会将它复制一份作为返回值,请大家不要忽略了这件事情。还有,A和CString很相像,但是我不想在 A 中开辟新内存块,而只是保留一个引用,并对引用的这块内存进行管理,这点和CString不太一样。