我们什么时候必须在 derived class c++ 中定义析构函数

When do we have to define a destructor in derived class c++

我是 c++ 的新手,我正面临内存泄漏,这让我想知道也许我没有理解正确的东西。

我有:

.h 文件

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
}

我有一个派生的 class,其中我依靠默认析构函数,而不是显式实现析构函数。

我想知道,如果我不使用 "new" 在派生 class 中分配内存,是否可以?

此外,我实现了自己的固定大小队列,它继承了 STL 的基础 Class 队列:

.h 文件

class VehicleParcelQueue:public std::queue<Parcel*>{
public:
    const static int MaxParcelsNum = 5;
    Result push(Parcel*);
};

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

可以看出,同样在这种情况下,我没有显式地实现析构函数。 我容易发生内存泄漏吗?

也许 pop 不为 Parcle 调用 delete 而是为指针调用析构函数? 谢谢

VehicleParcelQueue中的默认析构函数不会删除queue中的指针指向的对象。这些是导致内存泄漏的对象。

您必须为 VehicleParcelQueue 实现析构函数,并确保删除 queue 中的所有 Parcel 对象。

之前的建议不会奏效,因为 queue 的析构函数将首先被调用。

你最好的选择是使用

VehicleParcelQueue:public std::queue<std::unique_ptr<Parcel>>{

VehicleParcelQueue:public std::queue<std::shared_ptr<Parcel>>{

当 VehicleParcelQueue 的实例超出范围时,将调用其析构函数,随后调用基础 class std::queue 的析构函数。 std::queue的析构函数会"free"队列的节点,但不会对每个节点存储的指针调用delete。您必须在 VehicleParcelQueue 的析构函数中手动执行此操作以避免泄漏。当然,如果其他对象仍然引用它们,您可能也不想删除这些对象。

Maybe pop doesn't calling delete for Parcle but destructor to pointers?

正确。它从队列中删除节点,但不调用指针上的 delete。您必须获取节点的内容,即指针并对其调用 delete。

除了 R Sahu 的回答,请注意 std::queue<> 析构函数是 不是 虚拟的,任何从指向 Base 的指针的删除都会调用未定义的行为(出于这个原因,你通常不应该从标准容器继承)。

您可能应该检查您的设计,例如使用 class 成员而不是继承,并且尽可能使用值而不是指针:

VehicleParcelQueue
{
    ...

    std::queue<Parcel> queue;
};