一、在编译期间实现多态
多态是指在不同的条件下表现出不同的状态,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成了子类函数。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。
网友评论