C++ 继承与虚函数

继承与虚函数

​ 基类与派生类也叫父类与子类。派生类拥有基类的全部成员(属性和函数),当时需要按照基类中设置的访问权限访问。

  • 函数

    在一个类中的非静态成员函数可以分为两类:

    1. 普通成员函数

      • 被派生类直接继承,不需要改变。
      • 编译时解析。
      • 派生类可以覆盖(隐藏)它。
    2. 虚函数

      • 基类希望派生类覆盖。

      • 除构造函数外,所有的非静态函数都可以被声明为虚函数。

      • 运行时解析。

  • 非虚函数的重载与虚函数

    class Base {
    public:
        virtual void run() { ... }
    };
    class D1: public Base {
    public:
        void run(int a) { ... } // 隐藏基类虚函数
    };
    class D2: public D1 {
    public:
        void run(int a) { ... } // 隐藏非虚函数
        void run() { ... } // 覆盖虚函数
    };
    
  • 类型转化

    • 指针和应用

      • 派生类向基类转换是隐式的
      • 基类向派生类转化,需要调用请求类型转化(static_cast或dynamic_cast)
    • 对象

      • 派生类向基类转化,会切割掉派生类的成员,保留基类成员

      • 基类向派生类转化,编译报错

  • 派生类构造函数

    ​ 每个类负责自己成员的初始化,派生类初始化基类成员,需要调用基类的构造函数(默认调用基类的默认构造函数)。

  • 基类静态成员

    ​ 派生类可以访问基类的静态成员,但是需要符合访问权限。

  • 动态绑定

    ​ 动态绑定发生在对一个指针或者引用调用虚函数。

    • 动态绑定 = 指针/引用 + 覆盖(override)虚函数
    • 静态绑定 = 对象 + 虚函数;对象 + 非虚函数;指针/引用 + 非虚函数
  • 虚函数的默认参数

    ​ 在调用一个虚函数的时候,虚函数默认参数的值由调用的静态类型决定。

    class A { public: virtual void print(int a = 10) {...} };
    class B: public A { public: void print(int a = 20) {...} };
    int main() 
    {
    	A *a = new B;
        a->print(); // 默认参数为10
        ...
    }
    
  • 回避虚函数机制

    ​ 使用作用域运算符 :: 可以强制使用虚函数的某个实现。

  • 名字查找与继承

    p->mem(); 
    该调用的查找步骤:
    1. 确定p的静态类型
    2. 在静态类型的继承链中由下至上的查找名字为mem的函数,找不到则报错。
    3. 找到mem后,进行类型检查。
    	3.1 mem是虚函数且通过指针或引用调用的该函数,则依据动态类型调用虚函数的版本。
    	3.2 mem不是虚函数或者通过对象调用的该函数,则进行常规函数调用。
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值