指针初始化正在覆盖该值



Dog.h

class Dog
{
public:
int *pVal;
Dog(int);
~Dog();
static int GetVal(Dog d);
};

Dog.cpp

Dog::Dog(int val)
{
pVal = new int;
*pVal = val;
}
Dog::~Dog()
{
delete pVal;
}
int Dog::GetVal(Dog d)
{
return *(d.pVal);
}

测试

Dog fido(20);
CHECK(Dog::GetVal(fido) == 20);
Dog rex(21);
CHECK(Dog::GetVal(fido) == 20);
CHECK(Dog::GetVal(rex) == 21);

第一个CHECK正常。然而,一旦我声明Dog-rex(21(,我的fido对象的pVal就会被21覆盖。通过调试,我注意到在构造函数中调用new int时,rex的pVal获得与fido对象的p瓦尔相同的内存地址。我试了很多,但什么也找不到。

初始化指针并为其赋值的正确方法是什么?

请帮忙。提前谢谢。

当您进行此调用时:

Dog::GetVal(fido);

您在GetVal的自变量中创建Dog副本。调用默认的复制构造函数,它只生成pVal的浅副本。因此,当副本超出范围时,pVal指向的内存将被删除,这将删除fido指向的内存。

一种修复方法是在GetVal中使用Dog&,这样可以避免复制。

static int GetVal(Dog &d);

更好的选择是为Dog提供一个复制构造函数,如下所示:

Dog(Dog const & d) 
{ 
pVal = new int{*(d.pVal)}; 
}

这是一个工作演示。

关于你的观察:

我注意到,在构造函数中调用new int时,rex的pVal会获得与fido对象的p瓦尔相同的内存地址。

如上所述,当您调用rex的构造函数时,为fido分配的内存已经释放,因此相同的内存可以用于rex。(当然,这并不能保证会发生(。

最新更新