指针初始化正在覆盖值

问题描述 投票:2回答:1

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);
}

Test

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

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

第一次检查正常。但是,一旦我声明Dog rex(21),我的fido对象的pVal就会被21覆盖。通过调试,我注意到在构造函数中调用new int时,rex的pVal得到了与fido对象的pVal相同的内存地址。我尝试了很多,但找不到任何东西。

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

请帮助。先感谢您。

c++ pointers constructor new-operator
1个回答
1
投票

拨打电话时:

Dog::GetVal(fido);

您对Dog的自变量进行GetValcopy。调用默认的复制构造函数,该复制构造函数仅复制pVal的浅表副本。因此,当副本超出范围时,将删除pVal指向的内存,这将删除fido指向的内存。

一个解决方法是在Dog&中使用一个GetVal,避免复制。

static int GetVal(Dog &d);

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

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

这里是工作demo

关于您的观察:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.