Does delete work with pointers to base class?(删除是否适用于指向基类的指针?)
问题描述
您是否必须传递 delete 与 new 返回的相同指针,或者您可以传递一个指向类基类型之一的指针?例如:
Do you have to pass delete the same pointer that was returned by new, or can you pass it a pointer to one of the classes base types? For example:
class Base
{
public:
virtual ~Base();
...
};
class IFoo
{
public:
virtual ~IFoo() {}
virtual void DoSomething() = 0;
};
class Bar : public Base, public IFoo
{
public:
virtual ~Bar();
void DoSomething();
...
};
Bar * pBar = new Bar;
IFoo * pFoo = pBar;
delete pFoo;
当然,这大大简化了.我真正想做的是创建一个充满 boost::shared_ptr 的容器,并将其传递给一些代码,该代码将在完成后将其从容器中删除.此代码对 Bar 或 Base 的实现一无所知,并将依赖 shared_ptr 析构函数中隐含的删除运算符来做正确的事情.
Of course this is greatly simplified. What I really want to do is create a container full of boost::shared_ptr and pass it to some code that will remove it from the container when it is finished. This code will know nothing of the implementation of Bar or Base, and will rely on the implied delete operator in the shared_ptr destructor to do the right thing.
这可能行得通吗?我的直觉说不,因为指针不会有相同的地址.另一方面, dynamic_cast
Can this possibly work? My intuition says no, since the pointers will not have the same address. On the other hand, a dynamic_cast<Bar*> should work, so somewhere the compiler is storing enough information to figure it out.
Thanks for the help, everybody who answered and commented. I already knew the importance of virtual destructors, as shown in my example; after seeing the answer I gave it a little thought, and realized the whole reason for a virtual destructor is this exact scenario. Thus it had to work. I was thrown by the absence of a visible means of converting the pointer back to the original. A little more thinking led me to believe there was an invisible means, and I theorized that the destructor was returning the true pointer for delete to release. Investigating the compiled code from Microsoft VC++ confirmed my suspicion when I saw this line in ~Base:
mov eax, DWORD PTR _this$[ebp]
跟踪汇编程序发现这是传递给删除函数的指针.谜团解开了.
Tracing the assembler revealed that this was the pointer being passed to the delete function. Mystery solved.
我已经修复了将虚拟析构函数添加到 IFoo 的示例,这是一个简单的疏忽.再次感谢所有指出这一点的人.
I've fixed the example to add the virtual destructor to IFoo, it was a simple oversight. Thanks again to everyone who pointed it out.
推荐答案
是的,它会工作,当且仅当基类析构函数是虚拟的,你已经为 Base
基类,但不适用于 IFoo
基类.如果基类析构函数是虚拟的,那么当你在基类指针上调用 operator delete
时,它使用动态调度通过在虚函数中查找派生类析构函数来确定如何删除对象表.
Yes, it will work, if and only if the base class destructor is virtual, which you have done for the Base
base class but not for the IFoo
base class. If the base class destructor is virtual, then when you call operator delete
on the base class pointer, it uses dynamic dispatch to figure out how to delete the object by looking up the derived class destructor in the virtual function table.
在您的多重继承的情况下,只有当您删除它的基类具有虚拟析构函数时,它才会起作用;其他基类可以没有虚拟析构函数,但前提是您不尝试通过其他基类指针删除任何派生对象.
In your case of multiple inheritance, it will only work if the base class you're deleting it through has a virtual destructor; it's ok for the other base classes to not have a virtual destructor, but only if you don't try to delete any derived objects via those other base class pointers.
这篇关于删除是否适用于指向基类的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:删除是否适用于指向基类的指针?
基础教程推荐
- C++ #define 1970-01-01
- 分别使用%o和%x以八进制或十六进制格式显示整 1970-01-01
- end() 能否成为 stl 容器的昂贵操作 2022-10-23
- 初始化变量和赋值运算符 1970-01-01
- C语言访问数组元素 1970-01-01
- C++定义类对象 1970-01-01
- C++按值调用 1970-01-01
- 明确指定任何或所有枚举数的整数值 1970-01-01
- 使用scanf()读取字符串 1970-01-01
- C++输入/输出运算符重载 1970-01-01