动多态与RTTI

复习内容

  • 什么是多态?(1)静多态:编译时期的多态,有被称为早绑定    代表:函数重载,模板(2)动多态:运行时期的多态,又被称为晚绑定    代表:继承中的多态
  • 动多态的产生条件:指针或引用调用虚函数+对象必须完整
  • 完整对象:构造函数执行完毕,析构函数还没开始
class Base 
{ 
public: 
    Base() 
    { 
        this->fun(); 
    } 
    virtual void fun() 
    { 
        cout << "Base::virtual void fun()" <<endl; 
    }
}; 
class Derive:public Base 
{ 
public: 
    Derive() 
    { 
        this->fun(); 
    } 
    virtual void fun() 
    { 
        cout << "Derive::virtual void fun()" <<endl; 
    }
} 
int main() 
{ 
    Derive d; //不是完整对象
    return 0; 
}

  • 构造函数能不能写成虚函数?不能,(1)构造函数无法通过指针或者引用调用(2)vfptr是在构造时候写入对象,而多态调用虚函数需要用到vfptr
  • 什么情况下析构函数必须写成虚函数?存在父类指针指向堆上的子类对象时,就必须把父类的析构函数写成虚函数(自己疑惑的一个问题,既然析构的父类的指针指向的是子类的析构函数,因为指针是指向父类的,所以会调用父类的析构函数,因为父类的虚构函数是虚函数,所以去虚函数表当中找,不是就可以找到父类的析构函数吗?----------因为子类在继承的时候,继承了父类的虚函数表,并且对相同的函数进行了覆盖,所以找到的是子类的析构函数。)
  • Derive* dp = new Base();//先在堆上申请空间,然后调用构造函数进行构造,如果子类对象中有虚函数,而父类空间中没有虚函数,释放delete dp时则会报错。所以父类指针指向堆上的子类对象时候,一定要确保父类中有虚函数。
  • vftable什么时候产生?在哪里存储?在编译时期产生的,在.rodata段存储
  • 类的编译顺序:(1)先编译类名(2)再编译成员名(3)最后编译成员函数函数体
  • 虚函数能不能被处理成内联?不能,虚函数需要将函数指针放到vftable,而内联函数在编译期展开,在release版本没有地址---------不太懂
  • 静态函数能不能被写成虚函数?不能,静态函数不依赖于对象,无法产生动多态。

RTTI

  • 全称:run time type info
  • RTTI实际上是一个指针,指向一个保存类信息的结构体type
int main()
{
    Base* p = new Derive();
    cout << typeid(p).name << endl; //输出class Base*
    cout << typeid(*p).name << endl;//输出class Derive,在这里调用会用到RTTI,产生多态
    delete p;
    return 0;
}
  • RTTI在编译时期产生,type结构体中的信息不可改,所以放在只读.rodata数据段

RTTI的作用

  • dynamic_cast:父类指针转为子类指针专用的类型强转,要求:                                                     (1)必须有RTTI     (2)父类指针指向的对象中的RTTI确实是子类的
int main()
{
    Base* p = new Derive();
    cout << typeid(p).name << endl;
    cout << typeid(*p).name << endl;

    Derive* pd = (Derive*)p;//C语言强转,可以让pd指向子类的指针,但是这种方法并不安全,因为并不确定p原来指向的是否为子类对象,所以可以用底下的方法
    Derive* pd = dynamic_cast<Derive*>p;//这也是一种强转方法,但是它在强转之前会检查,p是不是尖括号里边的类型
                                        //如果不是,程序会崩溃
    delete p;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值