动态转换后删除指针是否安全?

8
void foo(MyClass* myClass)
{
    BaseClass* pBaseClass = dynamic_cast<BaseClass*>(myClass);
    delete myClass;   // <-------------- Does this affects on pBaseClass ?
}

一般而言,dynamic_cast如何工作?(它是否像复制构造函数一样工作?)

如果你确实想要一份拷贝(并且假设BaseClass确实是一个基类),那么请使用 BaseClass bc = *class; - john
如果BaseClass实际上是一个基类,那么使用dynamic_cast有什么意义?或者说,任何类型转换都有什么意义呢? - AnT stands with Russia
如果您担心删除指向基类的指针可能无法正确释放内存,请参见此处:https://dev59.com/xXVC5IYBdhLWcg3wcgmd - MasterHD
3个回答

7

不行,那是不安全的dynamic_cast 只是一种类型转换 - 原始指针和转换后的指针都指向同一个对象。

如果涉及多重继承,则转换后的指针可能会指向略有不同的地址,但仍然指向同一对象 - 不会发生对象复制。

编辑:我的意思是“不安全”在于“在你delete myClass之后,pBaseClass成为悬空指针(dangling pointer)。” 这仍然是合法代码,只是相当危险。


1
为什么不呢?dynamic_cast 要么成功,那么就存在一个继承关系,使得转换和调用 delete 都是合法的(正确的析构函数将被虚拟分派)。或者 dynamic_cast 返回 nullptr,这也是安全的。标准将 delete nullptr 定义为无操作。 - Damon
@Damon 添加了一份解释;我强烈印象中,这就是原帖作者想要的“安全”的意思。 - Angew is no longer proud of SO
1
啊,好的,我没有考虑到在删除后仍然尝试使用原始指针的情况。有道理 :-) - Damon

6

请注意,class不是一个有效的变量名,因为它是一个关键字。我会用c来代替它。

dynamic_cast后删除指针是安全的吗?

是的,但要注意,在删除它们所指向的对象后,这两个指针都无效。之后不能再使用任何指针值。

一般而言,dynamic_cast是如何工作的?

它将一个指向类类型的指针或引用转换为指向不同类类型的指针或引用,并在运行时检查转换是否有效。在这种情况下,如果BaseClass与对象的动态类型相同或是其基类,则强制转换将成功(给出有效指针)。否则,它将失败(给出空指针)。

如果您将*c强制转换为引用类型,则失败将导致异常(std::bad_cast),因为不存在空引用。

它像复制构造函数一样工作吗?

不是的。复制构造函数是用于复制对象的。这不是复制,只是改变指向它的指针的类型。复制看起来像:

BaseClass bc = *c;

请注意,bc 的类型是 BaseClass,而不是 c 的类型(c 为从 BaseClass 派生的类);这被称为“切片”,因为对象的派生部分被“切掉”而不是被复制。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接