我有一个代表 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.
那么,我怎样才能避免警告呢?
现在,当你运行这段代码时:
delete bagPtr;
来自基于链接的实现的析构函数未被调用。
template<class ItemType>
class BagInterface{
public:
.....
virtual ~BagInterface() = default;
};
如果您要通过指向 BagInterface 的指针删除从 BagInterface 派生的类(或者如果指向 BagInterface 的派生类的
sharedpointer<BagInterface>
超出范围),则需要此析构函数。
我的基于链接的实现使用的是虚拟析构函数,因为 与基于数组的实现不同,它是动态分配内存 最终它必须使用'delete'关键字删除实例 以避免内存泄漏。
这就是为什么你的基类需要一个虚拟析构函数:如果你没有,当你通过基类的指针删除派生类时,你会得到未定义的行为。
通过指向基的指针删除对象会调用未定义的行为 除非基类中的析构函数是虚拟的。 来源在这里