gpt4 book ai didi

c++ - 删除抽象非虚拟 dtor C++

转载 作者:行者123 更新时间:2023-12-02 09:57:45 26 4
gpt4 key购买 nike

关闭。这个问题需要details or clarity .它目前不接受答案。












想改进这个问题?通过 editing this post 添加详细信息并澄清问题.

1年前关闭。




Improve this question




我有一个代表抽象数据类型“包”的接口(interface)。为了实现这种抽象数据类型,我使用了基于数组和基于链接的实现。
这里是类的定义
编辑正如您所指出的,我已将虚拟析构函数添加到我的基类

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 操作。
我创建了一个函数,该函数将指针作为输入来表示包。
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
我尝试了其中一个建议,即:

Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.


并且还尝试将虚拟析构函数添加到 BagInterface,但它没有用。(编辑:我了解到我应该添加虚拟析构函数 :))
我不明白这个问题,因为两个派生类都有自己的析构函数,arrayBag 有默认析构函数,linkedBag 有虚拟析构函数。
那么,我怎样才能避免警告呢?

最佳答案

现在,当您运行此代码时:

delete bagPtr;
不调用基于链接的实现的析构函数。
template<class ItemType>
class BagInterface{

public:
.....
virtual ~BagInterface() = default;
};
如果要通过指向 BagInterface 的指针删除从 BagInterface 派生的类(或者如果指向 BagInterface 派生类的 sharedpointer<BagInterface> 超出范围),则需要此析构函数。

My link based implementation is using virtual destructor becauseunlike array based implementation it's dynamically allocating memoryand eventually it has to delete instance by using 'delete' keyword dueto avoid from memory leaks.


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

Deleting an object through pointer to base invokes undefined behaviorunless the destructor in the base class is virtual.source here

关于c++ - 删除抽象非虚拟 dtor C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64379833/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com