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

cngwdvgl  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(143)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

两年前关闭了。
这篇文章是编辑和提交审查48分钟前。
Improve this question
我有一个代表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.
}

阵列袋析构程序

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

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

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.

那么,我该如何避免这种警告呢?

06odsfpq

06odsfpq1#

现在,当您运行以下代码时:

delete bagPtr;

不调用基于链接的实现的析构函数。

template<class ItemType>
class BagInterface{

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

如果要通过指向BagInterface的指针删除从BagInterface派生的类(或者如果指向BagInterface派生类的sharedpointer<BagInterface>超出作用域),则需要此析构函数。
我的基于链接的实现使用虚析构函数,因为与基于数组的实现不同,它是动态分配内存的,最终它必须使用"delete"关键字删除示例,以避免内存泄漏。
这就是在基类中需要虚析构函数的原因:如果你没有,当你通过基类的指针删除一个派生类时,你会得到未定义的行为。
除非基类中的析构函数是虚的,否则通过基类指针删除对象会调用未定义的行为。source here

相关问题