2013-11-20 54 views
5
void foo(MyClass* myClass) 
{ 
    BaseClass* pBaseClass = dynamic_cast<BaseClass*>(myClass); 
    delete myClass; // <-------------- Does this affects on pBaseClass ? 
} 

一般如何dynamic_cast实际工作? (它是否像复制构造函数一样工作?)dynamic_casting后删除指针是否安全?

+0

如果你要一个副本(并假设BaseClass的实际上是一个基类)一个体面的解释,然后'BaseClass的BC = *类;' – john

+0

如果'BaseClass'是实际上是* base *类,那么'dynamic_cast'的意义是什么?或者有关于此事的演员? – AnT

回答

5

(请注意,class不是有效的变量名称,因为它是一个关键字,所以我将其称为c)。

dynamic_casting后删除指针是否安全?

是的;但要注意,删除指向的对象后,两个指针都是无效的。之后您不能使用任何一个指针值。

一般dynamic_cast实际上是如何工作的?

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

如果您将*c转换为引用类型,那么失败将导致异常(std::bad_cast),因为不存在空引用之类的事情。

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

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

BaseClass bc = *c; 

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

7

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

被转换的指针可能会指向一个略微不同的地址(如果涉及多重继承),但它仍然指向(同一个对象) - 不发生对象复制。

编辑:我的意思是在这个意义上“不安全”“你delete myClass后,pBaseClass是一个悬摆指针。”不过,它仍然是合法的代码。只是相当危险。

+0

为什么不呢? 'dynamic_cast'要么成功,那么就存在一个继承关系,它使得cast和calling'delete'合法(正确的析构函数将被虚拟调度)。或'dynamic_cast'返回'nullptr',这也是安全的。该标准将'delete nullptr'定义为no-op。 – Damon

+0

@Damon增加了一个解释;我有一个强烈的印象,那就是OP之后的“安全”的意义。 – Angew

+1

好的,我不认为有人可能会尝试删除后仍然使用原始指针。有效点:-) – Damon