C++学习之两种向下转型

   1)静态转型(强制转换)static_cast<子类指针或引用>(父类指针或引用):把父类的指针或引用强制转换为子类,返回子类的地址,是不安全的转换。
        [总结]:static_cast<  >(   )
                     ①.< >中必须是子类的指针或引用
                  ②.( )中的指针指向的是子类空间或者子类对象时,则转型是安全的
    1)动态转型(强制转换)dynamic_cast: 把父类指针或引用转换为子类指针或引用,转换成功则返回子类的地址,不成功返回NULL。
        [总结]:dynamic_cast<  >(   )
               ①.使用dynamic转换时,父类与子类要构成多态条件
                     ②.< >中必须是子类的指针或引用
                  ③.( )中的指针指向的是子类空间或者子类对象时,则转型是安全的

不懂可以参考以下代码理解以及运行结果

#include <iostream>
using namespace std;

class A{
public:
    A(int _a = 10){
        a = _a;
    }
    virtual void print(){
        cout<<"    a= "<<a<<endl;
    }
private:
    int a;
};

class B : public A{
public:
    B(int _a=11,int _b =12 ):A(_a){
        b = _b;
    }
    void print(){
        cout<<"    b= "<<b<<endl;
        A::print();
    }
private:
    int b;
};
int main(int argc, const char * argv[]) {
    A a;
    B b(20,30);
    
    //向下转换的两种形式
    /*静态转型(强制转换)static_cast: 把父类指针或引用强制转换为子类指针或引用,返回子类的地址,是不安全的转换。*/
    /*
     总结:static_cast<  >(   )
     1.<>中必须是子类的指针或引用
     2.()中的指针指向的是子类空间或者子类对象时,则转型是安全的
     3.
     */

    
    
    /* cout<<"***************静态转换的不安全事例(指针)******************"<<endl;
    A* a_ptr = &a;//父类指针指向子类空间 0x2
    //格式 使用静态转换(强转)
    B* q =  static_cast<B*>(a_ptr); //应该返回NULL表示不成功 把父类指针强转为子类空间 但是父类没有子类的b值,所以不安全 b为随机值
    q->print();//b 0 a 10 不安全(指针)
    
   cout<<"***************静态转换的安全形式(指针)***************"<<endl;
    B*w = &b;//0x1 这个空间里有子类的数据,安全
    A* m = w;//0x1
    B* y = static_cast<B*>(m);//0x1改变指针的类型 而没有改变空间的数据
    y->print();
    
    cout<<"***************静态转换的不安全事例(引用)******************"<<endl;
    B bb = static_cast<B&>(a);
    bb.print();
    
     cout<<"***************静态转换的安全事例(引用)******************"<<endl;
    B yy = static_cast<B&>(*m);
    yy.print();
    */
    
    //-----------------------------------------------------------------------------------------------------------------------------

    /*动态转型(强制转换)dynamic_cast: 把父类指针或引用转换为子类指针或引用,转换成功则返回子类的地址,不成功返回NULL。*/
    /*
     总结:dynamic_cast<  >(   )
     1.使用dynamic转换时,父类与子类要构成多态条件
     2.<>中必须是子类的指针或引用
     3.()中的指针指向的是子类空间或者子类对象时,则转型是安全的
     3.
     */

    
    
    
    //使用动态转换
    cout<<"**************动态转换对于不安全的处理,返回NULL(指针)*********\n";
    A* pp = &a;
    B* qq = dynamic_cast<B*>(pp);//不安全 qq为NULL
    if(qq){
        cout<<"转换成功\n";
        qq->print();
    }else{
        cout<<"转换不成功\n";
    }
    
       cout<<"**************动态转换对于不安全的处理,返回NULL(引用)*********\n";
//    B Derived = dynamic_cast<B&>(a);//崩
//    Derived.print();
    
      cout<<"**************安全动态转换(指针)*********\n";
    B* ptr = &b;
    A* ptr2 = ptr;
    B* ptr3 = dynamic_cast<B*>(ptr2);
    if(ptr3){
        cout<<"转换成功\n";
        ptr3->print();
    }
    
    cout<<"**************安全动态转换(引用)*********\n";
    B kk = dynamic_cast<B&>(*ptr2);
    cout<<"转换成功\n";
    kk.print();
    
  
    return 0;
}




运行结果:

运行结果

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值