我们什么时候必须在派生类c++; 我对C++有点陌生,我正面临内存泄漏,这让我想我可能没有理解什么。
我有: .h文件我们什么时候必须在派生类c++; 我对C++有点陌生,我正面临内存泄漏,这让我想我可能没有理解什么。,c++,destructor,virtual-destructor,C++,Destructor,Virtual Destructor,我有: .h文件 class DeliveryVehicle{ public: //c'tor DeliveryVehicle(const char* ID, Quality quality); //d'tor virtual ~DeliveryVehicle(); ... protected: VehicleParcelQueue parcelQueue_; } .c文件 DeliveryVehicle::~DeliveryVehicle(
class DeliveryVehicle{
public:
//c'tor
DeliveryVehicle(const char* ID, Quality quality);
//d'tor
virtual ~DeliveryVehicle();
...
protected:
VehicleParcelQueue parcelQueue_;
}
.c文件
DeliveryVehicle::~DeliveryVehicle(){
while(!parcelQueue_.empty()) parcelQueue_.pop();
// pop() calls removed element destructor
}
我有一个派生类,在该类中我依赖于默认析构函数,而不是显式实现析构函数
我想知道,如果我不使用“new”在派生类中分配内存,可以吗
此外,我还实现了自己的固定大小队列,它继承了STL的基类队列:
.h文件
class VehicleParcelQueue:public std::queue<Parcel*>{
public:
const static int MaxParcelsNum = 5;
Result push(Parcel*);
};
class VehicleParcelQueue:公共标准::队列{
公众:
常量static int MaxParcelsNum=5;
结果推送(包裹*);
};
.cpp文件
typedef enum result{SUCCESS = 1,FAILURE = 0} Result;
Result VehicleParcelQueue::push(Parcel* pParcel){
if (size() >= 5) return FAILURE;
else{
queue<Parcel*>::push(pParcel);
return SUCCESS;
}
typedef枚举结果{SUCCESS=1,FAILURE=0}结果;
结果车辆PARCELQUEUE::推送(地块*pParcel){
如果(size()>=5)返回失败;
否则{
队列::push(pParcel);
回归成功;
}
可以看出,在本例中,我没有显式实现析构函数。
我容易内存泄漏吗
也许pop并没有调用Parcle的delete,而是调用指向指针的析构函数?
谢谢车辆ParcelQueue中的默认析构函数不会删除
队列中指针指向的对象。这些对象是导致内存泄漏的原因
您必须为车辆ParcelQueue
实现析构函数,并确保删除队列中的所有地块
对象。
前面的建议不起作用,因为将首先调用队列
的析构函数
你最好的选择是使用
VehicleParcelQueue:public std::queue<std::unique_ptr<Parcel>>{
VehicleParcelQueue:公共标准::队列{
或
VehicleParcelQueue:公共标准::队列{
车辆ParcelQueue
中的默认析构函数不会删除队列中指针指向的对象。这些对象是导致内存泄漏的原因
您必须为车辆ParcelQueue
实现析构函数,并确保删除队列中的所有地块
对象。
前面的建议不起作用,因为将首先调用队列
的析构函数
你最好的选择是使用
VehicleParcelQueue:public std::queue<std::unique_ptr<Parcel>>{
VehicleParcelQueue:公共标准::队列{
或
VehicleParcelQueue:公共标准::队列{
当VehicleParcelQueue的实例超出范围时,将调用其析构函数,然后调用基类std::queue的析构函数。std::queue的析构函数将“释放”队列的节点,但不会为每个节点中存储的指针调用delete。您必须在VehicleParcelQueue的析构函数中手动执行此操作以避免泄漏。当然,如果其他对象仍引用这些对象,您也可能不希望删除这些对象
也许pop并没有调用Parcle的delete,而是调用指向指针的析构函数
正确。它会从队列中删除节点,但不会对指针调用delete。您必须获取节点的内容,即指针并对其调用delete。当VehicleParcelQueue的实例超出范围时,将调用其析构函数,然后调用基类std::queue的析构函数。std的析构函数::队列将“释放”队列中的节点,但不会为每个节点中存储的指针调用delete。您必须在VehicleParcelQueue的析构函数中手动执行此操作以避免泄漏。当然,如果其他对象仍引用这些对象,您也可能不希望删除这些对象
也许pop并没有调用Parcle的delete,而是调用指向指针的析构函数
正确。它会从队列中删除节点,但不会对指针调用delete。您必须获取节点的内容,即指针并对其调用delete。除了R Sahu answer之外,请注意std::queue
析构函数是非虚拟的,从指针到基的任何删除都将调用未定义的行为(因此,通常不应从标准容器继承)
您可能应该检查您的设计,例如使用类成员而不是继承,如果可能的话,将值优先于指针:
VehicleParcelQueue
{
...
std::queue<Parcel> queue;
};
VehicleParcelQueue
{
...
std::队列;
};
除了R Sahu answer之外,请注意,std::queue
析构函数是非虚拟的,从指向基的指针中删除任何内容都将调用未定义的行为(因此,通常不应从标准容器继承)
您可能应该检查您的设计,例如使用类成员而不是继承,如果可能的话,将值优先于指针:
VehicleParcelQueue
{
...
std::queue<Parcel> queue;
};
VehicleParcelQueue
{
...
std::队列;
};
您提供的代码没有内存泄漏,但您也没有显示完整的示例。您有没有理由不能使用队列
?没有指针的代码比有指针的代码更简单。在这里完成后,您可能希望对代码进行进一步检查。请尝试codereview.stackexchange.com我发现了一些潜在的问题问题。您提供的代码没有内存泄漏,但您也没有显示完整的示例。有什么原因不能使用队列
?没有指针的代码比有指针的代码更简单。在这里完成后,您可能希望对代码进行进一步检查。请尝试codereview.stackexchange.com我发现了一些潜在的问题问题。此解决方案有问题,因为正如R Sahu所指出的,std::queue的析构函数不是虚拟的。最好不要从中继承。此解决方案有问题,因为正如R Sahu所指出的,std::queue的析构函数不是虚拟的。最好不要从中继承。