C++多态性

1.运算符重载

#include<iostream>
using namespace std;

class Complex{
    public:
        Complex(double r=0.0,double i=0.0):real(r),imag(i){}
        Complex operator+(const Complex &c2) const;//运算符+重载成员函数
        void display() const;
    private:
        double real;
        double image;
};

Complex Complex::operator+(const Complex &c2) const{
    return Complex(real+c2.real,image+c2.image);//创建一个临时无名对象作为返回值
}

void Complex::display() const{
    cout<<"("<<real<<","<<image<<")"<<endl;
}

2虚函数

  如果需要通过基类的指针指向派生类的对象,并访问某个与基类同名的成员,那么首先在基类中将这个同名函数说明为虚函数。这样,通过基类类型的指针,就可以是属于不同派生类的不同对象产生不同的行为,从而实现运行过程的多态。

#include<iostream>
using namespace std;

class Base1{
    public:
        virtual void display() const;//虚函数
};
void Base1::display() const{
        cout<<"Base1::display()"<<endl;
}

class Base2:public Base1{  //共有派生类Base2定义
public:
    void display() const;//覆盖基类的函数
};
void Base2::display() const{
    cout<<"Base2::display()"<<endl;
}

class Derived:public Base2{
    public:
        void display() const;//覆盖基类的虚函数
};
void Derived:display() const{
    cout<<"Derived::display()"<<endl;
}

void fun(Base1 * ptr){//参数为指向基类对象的指针
    ptr->display();//“对象指针->成员名”
}

  只有虚函数是动态绑定的,如果派生类需要修改基类的行为(即重写与基类函数同名的函数),就应该在基类中将相应的函数声明为虚函数。而基类中声明的非虚函数,通常代表那些不希望被派生类改变的功能,也是不能实现多态的。一般不要重写继承而来的虚函数(虽然语法对此没有强制要求),应为那会导致通过基类指针和派生类的指针或对象调用同名函数式,产生不同的结果,从而引起混乱。只有通过基类的指针或引用调用虚函数时,才会发生动态绑定。

  如果一个类的析构函数是虚函数,那么由他派生而来的所有子类的析构函数也是虚函数。

3.纯虚函数与抽象类

  抽象类是一种特殊的类,他为一个类族提供统一的操作界面。可以说,建立抽象类,就是为了通过他多态地使用其中的成员函数。抽象类处于类层次的上层,一个抽象类自身无法实例化,也就是说我们无法顶第一个抽象类的对象,只能通过继承机制,生成抽象类的非抽象派生类,然后再实例化。声明为纯虚函数之后,基类中就可以不再给出函数的实现部分。

#include<iostream>
using namespace std;

class Base1{
    public:
        virtual void display() const=0;//纯虚函数
};

class Base2:public Base1{
    public:
        void display() const;//覆盖基类的虚函数
};
void Base2::display() const{
    cout<<"Base2::display()"<<endl;
}

class Derived:public Base2{
    public:
        void display() const;//覆盖基类的虚函数
};
void Derived:display(() const{
    cout<<"Derived::display()"<<endl;
}

void fun(Base1 * ptr){ //参数为指向基类对象的指针
    ptr->display();  //‘对象指针->成员名"
}

 

posted @ 2019-08-13 23:25  喜琅琅  阅读(144)  评论(0编辑  收藏  举报