在C ++中使用Static_cast向下转换

class base { base(); virtual void func(); } class derived : public base { derived(); void func(); void func_d(); int a; } main { base *b = new base(); sizeof(*b); // gives 4. derived * d = static_cast<derived*>(b); sizeof(*d); // gives 8- means whole derived obj size..why? d->func_d(); } 

在上面的代码中,我做了一个向基类对象指向派生类指针的基指针的向下转换。 我想知道如何派生指针具有整个派生类对象。 我可以调用派生类函数(仅在派生类中声明)。 我在这里没有得到这个概念。

使用static_cast将对象转换为types,实际上并不会产生未定义的行为 。 UB的症状差别很大。 没有什么说UB不能允许派生成员函数被调用成功(但没有什么可以保证它,所以不要指望它)。

C ++标准(C ++ 0x文字)的第5.2.9节( [expr.static.cast] )中介绍了使用static_cast向下转换的规则:

一个“指向cv1 B指针”的types的值,其中B是一个类的types,可以被转换为types“指向cv2 D指针”,其中D是从B派生的类,如果从“指针到D “到”指向B指针“时, cv2cv1具有相同的cv资格,或者具有比cv1更高的cv资格,并且B既不是D的虚拟基类也不是D的虚拟基类的基类。 空指针值被转换为目标types的空指针值。 如果“指向cv1 B指针”types的指针指向实际上是typesD的对象的子对象的D ,则生成的指针指向Dtypes的封闭对象。 否则,转换的结果是不确定的。

执行运行时检查的唯一转换是dynamic_cast<>() 。 如果在演播室中演员不能工作,那么应该使用这个演员。

因此,从叶 – >根(铸造) static_cast<>()铸造工作正常。
但是从root-> leaf(向下投射)投射是危险的,(在我看来)应该总是用dynamic_cast<>()来完成,因为运行时信息将会依赖于它。 成本是轻微的,但总是值得付出的安全。

sizeof在编译时存在。 它在运行时既不知道也不关心,你的基础对象不指向derived 。 您试图通过运行时variables影响编译时行为,这是根本不可能的。