C++ 多态的实现和原理

2019-04-23  本文已影响0人  石器时代小古董

多态的实现
虚函数原理

一、在编译期间实现多态

多态是指在不同的条件下表现出不同的状态,C++中通过重载函数的方法可以在编译期间实现多态。

在编译时编译器会根据参数列表的不同寻找合适的函数。

int Add(int left, int right)
{
    return left + right;
}
double Add(double left, int right)
{
    return left + right;
}

int main()
{
    Add(10, 20);
    Add(10.0,20);  //正常代码
    return 0;
}
二、使用虚函数实现多态

C++中运行时多态可以通过声明一个虚函数来实现。虚函数分为纯虚方法和半虚方法,纯函数父类没有实现版本,完全交给子类,且必须实现。半虚函数父类可以实现,子类需要重写,他们都由关键字virtual修饰。

运行时多态的条件:
● 必须是集成关系
●基类中必须包含虚函数,并且派生类中一定要对基类中的虚函数进行重写。
●通过基类对象的指针或者引用调用虚函数。

重写虚函数时一定要保证函数的返回值,参数列表,函数名称完全一致

// 半虚函数 父类实现,但希望子类重写
virtual void withDraw(){
    a=10;
};
// 纯虚函数
virtual void onDraw()=0;
virtual ~Clazz();

使用虚函数实现多态示例

#ifndef student_hpp
#define student_hpp

#include <stdio.h>
#include <string>
using namespace std;
class Student{
private:
    int mAge;
    string mName;
protected:
    int mClazz;
public:
    Student() {};
    void setName(const string &age);
    string getName() const;
    void setAage(int &age);
    int getAge() const;
    virtual void setClassMate(int num){
        mClazz=num;
        std::cout<<“call parent method”<<std::endl;
    };
    virtual int getClassMate(){
        return mClazz;
    };
    virtual ~Student() {}
};

class Guo:public Student{
public:
    Guo() {};
    virtual void setClassMate(int num){
        mClazz = num;
        std::cout<<“call child method”<<std::endl;
    };
    virtual int getClassMate(){
        return mClazz;
    };
    virtual ~Guo();
};
void setClass(Student &st,int clazz){
  st.setClassMate(clazz);
}
int main(){
   Student student;
   Guo guo;
   setCLass(student);
   setClass(guo)
}

以下函数不能作为虚函数
1)友元函数,它不是类的成员函数
2)全局函数
3)静态成员函数,它没有this指针
3)构造函数,拷贝构造函数,以及赋值运算符重载(可以但是一般不建议作为虚函数)

三、虚函数的实现原理

一个类中如果有虚函数声明,那么这些函数会由一个虚函数表来维护
1) 每个父类都有自己的虚表。

2) 子类的成员函数被放到了第一个父类的表中。

3) 内存布局中,其父类布局依次按声明顺序排列。

4) 每个父类的虚表中的函数都被overwrite成了子类函数。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。

上一篇 下一篇

猜你喜欢

热点阅读