如何解决删除抽象的非虚拟dtor c ++
我有一个表示抽象数据类型“包”的接口。为了实现该抽象数据类型,我使用了基于数组和基于链接的实现。
这里是类的定义
编辑正如您所指出的,我已将虚拟析构函数添加到我的基类中
template<class ItemType>
class BagInterface{
public:
virtual int getCurrentSize() const = 0;
virtual bool isEmpty() const = 0;
virtual bool add(const ItemType& newEntry) = 0;
virtual bool remove(const ItemType& anEntry) = 0;
virtual int getFrequencyOf(const ItemType& anEntry) const = 0;
virtual bool contains (const ItemType& anEntry) const = 0;
virtual void clear() = 0;
virtual vector<ItemType> toVector() const = 0;
virtual ~BagInterface() = default;
};
#endif /* BagInterface_hpp */
我的2个派生类按其方式实现了这些方法。
我基于链接的实现使用的是虚拟析构函数,因为与基于数组的实现不同,它是动态分配内存的,最终为了避免内存泄漏,必须使用'delete'关键字删除实例。
链接包的破坏者
template<class ItemType>
LinkedBag<ItemType>::~LinkedBag(){
clear(); // Clears bag's content.
}
arraybag的析构函数
template<class ItemType>
ArrayBag<ItemType>::~ArrayBag(){
clear();
}
在解决所有实现问题之后,我想测试我的ADT操作。
我创建了一个函数,该函数以指针作为输入来表示bag。
void bagTester(BagInterface<int>* bagPtr){
// do some test }
在我的主要功能中,完成测试后,我想删除我的bagPtr,因为我已经完成了,所以现在该删除它了。
int main(){
BagInterface<int>* bagPtr = nullptr;
char userChoice;
cin>> userChoice;
if(userChoice == 'A'){
bagPtr = new ArrayBag<int>(); // Array based implementation
}else if(userChoice == 'L'){
bagPtr = new LinkedBag<int>(); // Link bases implementation
}
bagTester(bagPtr); // test my bag
delete bagPtr; // and now i'm finished with test let's delete the pointer
bagPtr = nullptr; // deallocate
}
**此时我的错误正在发生,编译器发出警告-> **
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.
我检查了此相关主题-> Suppress delete-non-virtual-dtor warning when using a protected non-virtual destructor
我尝试了其中显示的一项建议,即:
准则4:基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的。
并且还尝试将虚拟析构函数添加到BagInterface,但这没有用。(编辑:我了解到我应该添加虚拟析构函数:))
我不明白问题所在,因为两个派生类都有自己的析构函数,arrayBag具有默认析构函数,linkedBag具有虚拟析构函数。
那么,如何避免警告?
解决方法
现在,当您运行此代码时:
delete bagPtr;
基于链接的实现中的析构函数未调用。
template<class ItemType>
class BagInterface{
public:
.....
virtual ~BagInterface() = default;
};
如果要通过指向BagInterface的指针删除从BagInterface派生的类(或者如果指向sharedpointer<BagInterface>
指向BagInterface派生类的指针超出范围),则需要此析构函数。
我基于链接的实现正在使用虚拟析构函数,因为 与基于数组的实现不同,它是动态分配内存的 最终它必须通过使用“ delete”关键字删除实例 避免内存泄漏。
这就是为什么在基类中需要一个虚拟析构函数的原因:如果您没有一个虚拟析构函数,那么当通过基类的指针删除派生类时,您将得到不确定的行为。
通过指向基址的指针删除对象会调用未定义的行为 除非基类中的析构函数是虚拟的。 source here
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。