考虑:
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();
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我做了一个基指针的向下转换,它指向基对象到派生类指针.我想知道派生指针如何具有整个派生类对象.我可以调用派生类函数(仅在派生类中声明).我没有在这里得到这个概念.
Ben*_*igt 21
使用static_cast投对象的类型,它实际上并不具有收益不确定的行为.UB的症状差异很大.没有什么可以说UB不能允许成功调用派生成员函数(但是没有任何东西可以保证它会被调用,所以不要指望它).
下面是使用的规则static_cast,可以在[expr.static.cast]C++标准的5.2.9()部分找到(C++ 0x措辞):
类型为"指向cv1的 指针"的prvalue
B,其中B是一个类类型,可以转换为类型为"指向cv2的 指针"的prvalueD,其中D是一个派生自的类B,如果是从"指针D"到"指针"的有效标准转换到B"的存在,CV2是相同的CV-资格,或更大的CV-资格比,CV1,并且B既不是虚基类的D,也不是基类的虚拟基类的D.空指针值将转换为目标类型的空指针值.如果"指向cv1的 指针B" 类型的prvalue指向B实际上是类型对象的子对象D,则生成的指针指向类型的封闭对象D.否则,演员的结果是不确定的.
进行运行时检查的唯一转换是dynamic_cast<>().如果演员阵容在运行时无法运行,则应使用此演员表.
因此从叶子 - >根(向上铸造)铸造static_cast<>()工作正常.
但是从root-> leaf(向下转换)进行转换是危险的,并且(在我看来)应该总是这样做,dynamic_cast<>()因为对运行时信息有依赖性.成本很低,但总是值得为安全付出代价.
sizeof存在于编译时.它既不知道也不关心在运行时,你的基础对象不指向a derived.您试图用运行时变量影响编译时行为,这从根本上是不可能的.