C++学习:第三章C++语言基础 - (十一)多态、虚函数、纯虚函数

虚函数的继承与实现

  1. 父类子类都是虚函数,则实现依旧是在子类。
  2. 父类的非虚函数中调用虚函数,在子类实现,依旧是按照子类实现的方式执行虚函数
#include <iostream>
#include <string>

using namespace std;

class Animal{
public:
    void play(){eat(); shout(); sleep(); }
    virtual void eat()  {cout << "class Animal eat "   << endl;};
    virtual void shout(){cout << "class Animal shout " << endl;};
    virtual void sleep(){cout << "class Animal sleep " << endl;};
};


class Tiger:public Animal{
public:
    virtual void eat()  {cout << "class Tiger eat "   << endl;};
    virtual void shout(){cout << "class Tiger shout " << endl;};
    virtual void sleep(){cout << "class Tiger sleep " << endl;};
};



int main(){

    Animal* p = NULL;
    p = new Tiger;
    p->play();

    delete p;

    getchar();
    return 0;
}

 

虚函数的析构

#include <iostream>
#include <string>
using namespace std;

class Animal{
public:
    Animal() {cout << "class Animal " ;shout();}

    //重点就是这个析构函数的 virtual
    virtual ~Animal(){cout << "class ~Animal " ;shout();}
    void play(){eat(); shout(); sleep(); }
    virtual void eat()  {cout << "class Animal eat "   << endl;};
    virtual void shout(){cout << "class Animal shout " << endl;};
    virtual void sleep(){cout << "class Animal sleep " << endl;};
};



class Tiger:public Animal{
public:
    Tiger() {cout << "class Tiger " ;shout();}
    ~Tiger(){cout << "class ~Tiger "  ;shout();}
    virtual void eat()  {cout << "class Tiger eat "   << endl;};
    virtual void shout(){cout << "class Tiger shout " << endl;};
    virtual void sleep(){cout << "class Tiger sleep " << endl;};
};



int main(){

    Animal* p = NULL;
    p = new Tiger;
    p->play();
    delete p;

    getchar();
    return 0;
}

 

纯虚函数

不会真正被执行,由子类来执行。有纯虚函数的类成为抽象类。

为了防止抽象类的方法被执行,编译器不允许实例化抽象类对象,但可以使用抽象类的指针或者引用指向子类对象。

virtual void eat()  = 0;

 

虚函数的实现原理

每个类都有一个隐含的虚表

多态原理:父类指针指向虚表中的子类指针,虚表中的指针指向子类的虚函数表,然后通过子类的虚函数表调用子类对象及其内部变量、方法。

父类指针--->虚函数表(VTable)--->子类虚表

#include <iostream>
#include <string>

using namespace std;

class A {
    double d;
};

class B : public A{
    double d;
public:
    void f(){}//普通函数在代码区,不占用类的存储空间
};

class C{
    double d;
public:
    virtual void f(){cout << "  class C  " << endl;}
    virtual void g(){cout << this << "  " << &d << endl;}
    virtual void h(){}
    virtual void i(){}
    virtual void j(){}
};

class D : public C{
    double d;
public:
    virtual void f(){cout << "  class D  " << endl;}
};



int main(){

    cout << sizeof(A) << endl;
    cout << sizeof(B) << endl;
    cout << sizeof(C) << endl;
    cout << sizeof(D) << endl;

    A* p = new B;
    C* q1 = new C;
    C* q2 = new D;

    q1->f();
    q2->f();

    q1->g();
    q2->g();

    cout << "======================" << endl;

    //通过指针赋值改变虚表中的指向关系
    //让q2所指对象的虚表指针指向C类虚函数表
    memcpy(q2, q1, 8);
    q1->f();
    q2->f();

    getchar();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值