gpt4 book ai didi

c++ - 类中的指针私有(private)属性,其中此类在 vector 中使用,生成错误双重释放或损坏

转载 作者:行者123 更新时间:2023-11-30 05:02:45 26 4
gpt4 key购买 nike

我已经在 C++ std c++11 中实现了类,代码两个测试 winstrument 类运行良好,但 station.cpp 的代码不起作用,它在

stationA.insertInstrument(instrumentC);

但在此之前我插入了更多的两个工具,内部容器是一个 vector ,我使用方法 push_back 来存储工具:

void WStation::insertInstrument(const WInstrument& instrument)
{
_instruments.push_back(instrument);
}

这是类的原型(prototype)

class WInstrument
{
public:
WInstrument(int serialNumber, std::string description, Type type);
~WInstrument();

bool operator==(const WInstrument& rhs) const;
bool operator!=(const WInstrument& rhs) const;

double read() const;

std::string getDescription() const;
int getSerialNumber() const;
Type getType() const;

private:
int _serialNumber = -1;
Type _type;
std::string _description;

private:
std::uniform_real_distribution<double> *_dist;
};

这是默认构造函数:

WInstrument::WInstrument(int serialNumber, std::string description, Type type):
_serialNumber(serialNumber),
_type(type),
_description(description)
{
switch(_type)
{
case wind:
{
_dist = new std::uniform_real_distribution<double>(0.0, 200.0);
break;
}
case temperature:
{
_dist = new std::uniform_real_distribution<double>(-20.0, 100.0);
break;
}
case humidity:
{
_dist = new std::uniform_real_distribution<double>(0.0, 100.0);
break;
}
}
}

我认为问题出在 *_dist,因为如果我不使用指针并直接实现,我将在其中使用函数 read,代码可以工作。在析构函数中,我使用 delete _dist。问题是我不明白这个问题。

完整代码在https://github.com/retiarus/test-winstrument中可用.

最佳答案

问题是 WInstrument 包含一个指向 uniform_real_distribution 的原始指针,该指针在您的析构函数中被删除,但您的类没有适当的复制构造函数或复制赋值运算符(参见 The Rule of Three )。

因为您没有定义复制构造函数或复制赋值运算符,编译器会自动为您创建一个,但它只是愚蠢地复制拥有的原始指针。

这里:

void WStation::insertInstrument(const WInstrument& instrument)
{
_instruments.push_back(instrument);
}

您正在将 WInstrument 的拷贝复制到 std::vector 中,现在您有两个 WInstrument 拷贝,它们都带有一个指针到相同的 uniform_real_distribution。当调用这两个对象的析构函数时,您会得到双重删除,因此会出现 error。 .

最简单的解决方案就是根本不使用指针,直接存储一个uniform_real_distribution:

class WInstrument
{
public:
WInstrument(int serialNumber, std::string description, Type type);

//...

private:
std::uniform_real_distribution<double> _dist;
};

WInstrument::WInstrument(int serialNumber, std::string description, Type type):
_serialNumber(serialNumber),
_type(type),
_description(description)
{
switch(_type)
{
case wind:
{
_dist = std::uniform_real_distribution<double>(0.0, 200.0);
break;
}
// ...
}
}

那么你根本不需要定义析构函数,你的问题就消失了。

Live demo .

次要细节:如果您按值存储 uniform_real_distribution,它会强制您处理 const 正确性,因为 uniform_real_distribution 上的 operator() 是不是常数。一种解决方案是使 WInstrument::read() 成为非常量。另一种解决方案是使 dist_ 可变,以便您可以在 const 成员函数中使用它。尽管您必须小心,因为通常 const 成员函数是线程安全的,而这不是。

关于c++ - 类中的指针私有(private)属性,其中此类在 vector 中使用,生成错误双重释放或损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49703419/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com