在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“指向cv2D
指针”,其中D
是从B
派生的类,如果从“指针到D
“到”指向B
指针“时, cv2与cv1具有相同的cv资格,或者具有比cv1更高的cv资格,并且B
既不是D
的虚拟基类也不是D
的虚拟基类的基类。 空指针值被转换为目标types的空指针值。 如果“指向cv1B
指针”types的指针指向实际上是typesD
的对象的子对象的D
,则生成的指针指向D
types的封闭对象。 否则,转换的结果是不确定的。
执行运行时检查的唯一转换是dynamic_cast<>()
。 如果在演播室中演员不能工作,那么应该使用这个演员。
因此,从叶 – >根(铸造) static_cast<>()
铸造工作正常。
但是从root-> leaf(向下投射)投射是危险的,(在我看来)应该总是用dynamic_cast<>()
来完成,因为运行时信息将会依赖于它。 成本是轻微的,但总是值得付出的安全。
sizeof
在编译时存在。 它在运行时既不知道也不关心,你的基础对象不指向derived
。 您试图通过运行时variables影响编译时行为,这是根本不可能的。