向下类型转换过程

Downcasting procedure

本文关键字:过程 类型转换      更新时间:2023-10-16

有谁能解释一下这种向下转换方式是否正确,或者我们应该使用显式类型转换?

#include<iostream>
using namespace std;
class base {
public:
    virtual void func() { cout<<"Base n"; }
            void fun()  { cout<<"fun"; }
};
class derived1 : public base {
public:
            void func() { cout<<"Derived 1n"; };
            void fun()  { cout<<"fun1"; }
};
class derived2 : public derived1 {
public:
            void func() { cout<<"Derived 2n"; }
            void fun()  { cout<<"fun2"; }
};

int main()
{
    base * var = new derived1;
    ((base *) var)-> fun();
    ((derived1 *) var)-> fun();
    ((derived2 *) var)-> fun(); 
    // How does this work?
}

((base *) var)-> fun();((derived1 *) var)-> fun(); 是有效的,但不是好的做法。你应该使用C++风格的铸造(static_cast, dynamic_cast ..),而不是c-style铸造。

((derived2 *) var)-> fun();无效的,因为var不是真正的derived2类。如果使用dynamic_cast进行强制转换,它将失败。但这里它工作,因为对象对齐C++。在代码部分中,派生成员通常按照定义的顺序排列在基成员之后。因此,在这种情况下,derived1::funderived2::fun将从相同的偏移量开始,因此调用它是有效的。虽然转换为derived2*后的对象无效,但它可以工作,因为fun不访问类的任何成员。但是这种行为是不可预测的,一定不能依赖于它或者使用这种代码

首先,这里base * var = new derived1;是向上铸造。

第二,用dynamic_cast做下铸件比较安全。

derived1 *d1 = dynamic_cast<derived1*>(var);
if(d1) d1->fun();
derived2 *d2 = dynamic_cast<derived2*>(var); // will return NULL
if(d2) d2->fun();