C++虚函数(virtual关键字)

1.虚函数(实现类的多态性)

       当函数被virtual关键字修饰时,该函数被称为虚函数,虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。虚函数最关键的特点是“动态联编”,它可以在运行时判断指针指向的对象,并正确调用对象的函数。      而函数的重载可以认为是多态,只不过是静态的。注意,非虚函数静态联编,效率要比虚函数高,但是不具备动态联编能力。
       只要基函数定义了virtual,继承类的该函数也就具有virtual属性
       c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用。

如果使用了virtual关键字,程序将根据引用或指针指向的 对象类型 来选择方法,否则使用引用类型或指针类型来选择方法。

  • 友元函数 构造函数 static静态函数 不能用virtual关键字修饰;
  • 普通成员函数 和析构函数 可以用virtual关键字修饰;
class A{
    private:
        int i;
    public:
        A();
        A(int num) :i(num) {};
        virtual void fun1();
        virtual void fun2();

    };

    class B : public A{
    private:
        int j;
    public:
        B(int num) :j(num){};
        virtual void fun2();// 重写了基类的方法
    };

int main{
    A a(1);
    B b(2);
    A *a1_ptr = &a;
    A *a2_ptr = &b;

    // 当派生类“重写”了基类的虚方法,调用该方法时
       // 程序根据 指针或引用 指向的  “对象的类型”来选择使用哪个方法
    a1_ptr->fun2();// call A::fun2();
    a2_ptr->fun2();// call B::fun1();

    // 否则 程序根据“指针或引用的类型”来选择使用哪个方法
    a1_ptr->fun1();// call A::fun1();
    a2_ptr->fun1();// call A::fun1();
}
   

2.纯虚函数

class CShape
{
public:
    virtual void Show()=0;
};

何时使用纯虚函数?
(1)当想在基类中抽象出一个方法,且该基类只做能被继承,而不能被实例化;
(2)这个方法必须在派生类(derived class)中被实现;
如果满足以上两点,可以考虑将该方法申明为pure virtual function.

  • 纯虚函数为后代类提供可覆盖的接口,但这个类中的版本决不会调用。
  • 含有一个或多个纯虚函数的类是抽象基类,抽象基类不能实例化。
  • 继承类只有重写这个接口才能被实例化

抽象类的规定
(1)抽象类只能用作其他类的基类,不能建立抽象类对象。
(2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。
(3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。

3.虚继承

虚继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。间接或直接地继承同一基类,会在子类中存在多份拷贝。这样将存在两个问题:①浪费存储空间;②存在二义性

例:类D继承来自类B1、B2,而类B1、B2都继承来自类A,如左图所示(A为非虚基类):
这里写图片描述         这里写图片描述
为了节省内存空间,可以将B1、B2对A的继承定义为虚继承,那么A就成了虚拟基类。如右图所示。

class A{};
class B1 :public virtual A{};
class B2 :public virtual A{};
class D  :public B1,public B2{};

 


 

发布了522 篇原创文章 · 获赞 213 · 访问量 24万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 像素格子 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览