C++ override总结

C++ override是面向对象思想实现的关键。override是指对父类的抽象方法进行重写,以使子类对父类的同一个接口拥有各自不同的实现,即多态。在C++中要实现真正的多态只能是对父类虚方法进行重写,一般情况下还应当加上override关键字,使得编译器帮助我们检查重写是否正确。对于父类的非虚方法不应当进行重写,如果重写了父类的非虚方法,实际上是覆盖(hide),而不可能构成override

eg:

class Base
{
public:
   virtual void say()const
   {
       cout<<"I'm Base"<<endl;
   }

   void run()const
   {
       cout<<"Base run"<<endl;
   }
};

class Derived:public Base
{
public:
    void say()const override
    {
        cout<<"I'm Derived"<<endl;
    }

    void run()const  ///加上overrride后编译器报错
    {
        cout<<"Derived run"<<endl;
    }
};

Derived d;
Base &b = d;
b.say();  ///output:I'm Derived
b.run();  ///output:Base run

C++构成override时,子类中的重写函数声明和父类中的虚函数必须严格一致即函数的参数个数,const属性,返回值类型等都要完全一致,对于返回值类型如果父类返回的是父类的指针或引用类型时,子类可以返回子类类型的指针和引用

eg:

class Base
{
public:
    virtual Base* clone()const
    {
        return new Base(*this);
    }
};

class Derived:public Base
{
public:
    Derived* clone()const override final ///ok,final关键字说明如果Derived有子类,
    {                                    ///则其子类不能对clone函数重写,
        return new Derived(*this);
    }
};

class BaseWrap
{
public:
    virtual Base* clone()const
    {
        return b.clone();
    }
private:
    Base b;
};

class DerivedWrap:public BaseWrap
{
public:
    Derived* clone()const override final ///ok
    {
        return d.clone();
    }
private:
    Derived d;
};

父类的虚函数还可以声明为纯虚函数,拥有纯虚函数的类成为抽象类,抽象类不能创建对象,但可以定义指向抽象类类型的指针和引用,纯虚函数可以实现,但是只能在类外实现,而且即使纯虚函数拥有实现,包含它的类也属于抽象类

class Base
{
public:
    virtual void say()const  = 0;
};

void Base::say()const
{
    cout<<"Base say"<<endl;
}

class Derived:public Base
{
public:
    void say()const override
    {
        Base::say();
        cout<<"Derived say"<<endl;
    }
};

Base b;  ///错误,抽象类不能创建对象
Derived d;
Base &b = d;
b.say();
///output:
///Base say
///Derived say

c++中的多重继承和函数重写遇上会发生什么呢?

eg:

class Basex
{
public:
    virtual void say()const
    {
        cout<<"Basex say"<<endl;
    }
};

class BaseY
{
public:
    virtual void say()const
    {
        cout<<"Basey say"<<endl;
    }
};

class Derived:public Basex,public BaseY
{
public:
    void say()const override final
    {
        cout<<"Derived say"<<endl;
    }
};

Derived d;
Basex &bx = d;
BaseY &by = d;

bx.say();   ///output:Derived say
by.say();   ///output:Derived say

如果还有虚继承,那么重载又会是怎样的呢?

eg:

class Base
{
public:
    virtual void say()const
    {
        cout<<"Base say"<<endl;
    }
};

class Basex:public virtual Base
{
public:
    void say()const override
    {
        cout<<"Basex say"<<endl;
    }
};

class Basey:public virtual Base
{
public:
    void say()const override
    {
        cout<<"Basey say"<<endl;
    }
};


class Basez:public virtual Base
{
};


///如果虚基类中的虚函数f被其不同的子类重写,而且这些子类又被同一个子类d继承,
///那么d类必须重写虚基类中继承的虚函数f,否则会产生歧义
class Deriveda:public Basex,public Basey   ///错误,虚基类Base中的虚函数say通过两个
{                           ///不同的子类Basex,Basey重写了,因此需要在Derived重写
};

class Derivedb:public Basex,public Basey
{
public:
    void say()const override final
    {
        cout<<"Derivedb say"<<endl;
    }
};

///如果虚基类到其子孙类d的继承路线上,只有其中一个子类dx重写了它的虚函数f
///那么d不必重写虚函数f,而且d中f的实现和dx的实现相同
class Derivedc:public Basex,public Basez
{
};

 Derivedb db;
 Derivedc dc;

 Base &bb = db,&bc = dc;
 Basex &bbx = db,&bcx = dc;
 Basey &bby = db;
 Basez &bcz = dc;

 bb.say();   ///output:Derivedb say
 bbx.say();  ///output:Derivedb say
 bby.say();  ///output:Derivedb say

 bc.say();   ///output:Derivedb say
 bcx.say();  ///output:Derivedb say
 bcz.say();  ///output:Derivedb say




















郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。