通过基类指针c++删除派生类[关闭]

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

我有一个代表 ADT“Bag”的界面。为了实现该抽象数据类型,我使用了基于数组和基于链接的实现。

这里是类的定义

edit 如您所指,我已将虚拟析构函数添加到我的基类中

template<class ItemType>
class BagInterface{

public:
    ... some methods

   ~BagInterface();
};


#endif /* BagInterface_hpp */

我的 2 个派生类在他们的路上实现了这些方法。

我的基于链接的实现使用虚拟析构函数,因为与基于数组的实现不同,它动态分配内存,最终它必须使用“delete”关键字删除实例,以避免内存泄漏。

链接包的析构函数

template<class ItemType>
LinkedBag<ItemType>::~LinkedBag(){
    clear(); // Clears bag's content.
}

arraybag 的析构函数

template<class ItemType>
ArrayBag<ItemType>::~ArrayBag(){
    clear();
}

为了测试我的实现,我创建了一个将指针作为输入来表示包的函数。

void bagTester(BagInterface<int>* bagPtr){
   // do some test }

我想通过下面的基类指针删除我的派生类。

  int main() {
     BagInterface<int>* bagPtr = nullptr; // base class pointer
    
     char userChoice;
     cin>> userChoice;
    
     if(userChoice == 'A'){
     bagPtr = new ArrayBag<int>(); // Array based implementation 
    }else if(userChoice == 'L'){
     bagPtr = new LinkedBag<int>(); // Link based implementation
    }

    bagTester(bagPtr); // test my bag
    
    delete bagPtr; // and now i'm finished with test let's delete the object
    bagPtr = nullptr; // to avoid dangling pointers
}

在那一点上我的错误发生了,编译器给出了警告 ->

In file included from main.cpp:2:
In file included from ./LinkedBag.hpp:5:
./BagInterface.hpp:36:31: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions]
    virtual ~BagInterface() = default;
                              ^
In file included from main.cpp:4:
./ArrayBag.hpp:28:5: error: exception specification of overriding function is more lax than base version
    ~ArrayBag();
    ^
main.cpp:48:22: note: in instantiation of template class 'ArrayBag<int>' requested here
        bagPtr = new ArrayBag<int>();
                     ^
./BagInterface.hpp:36:13: note: overridden virtual function is here
    virtual ~BagInterface() = default;
            ^
In file included from main.cpp:2:
./LinkedBag.hpp:25:1: error: exception specification of overriding function is more lax than base version
~LinkedBag();
^
main.cpp:52:22: note: in instantiation of template class 'LinkedBag<int>' requested here
        bagPtr = new LinkedBag<int>();
                     ^
./BagInterface.hpp:36:13: note: overridden virtual function is here
    virtual ~BagInterface() = default;
            ^
1 warning and 2 errors generated.

那么,我怎样才能避免警告呢?

c++ pointers abstract-class abstract-data-type
1个回答
2
投票

现在,当你运行这段代码时:

delete bagPtr;

来自基于链接的实现的析构函数未被调用。

template<class ItemType>
class BagInterface{

public:
.....
virtual ~BagInterface() = default;
};

如果您要通过指向 BagInterface 的指针删除从 BagInterface 派生的类(或者如果指向 BagInterface 的派生类的

sharedpointer<BagInterface>
超出范围),则需要此析构函数。

我的基于链接的实现使用的是虚拟析构函数,因为 与基于数组的实现不同,它是动态分配内存 最终它必须使用'delete'关键字删除实例 以避免内存泄漏。

这就是为什么你的基类需要一个虚拟析构函数:如果你没有,当你通过基类的指针删除派生类时,你会得到未定义的行为。

通过指向基的指针删除对象会调用未定义的行为 除非基类中的析构函数是虚拟的。 来源在这里

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