C++函数重载、重写与重定义

  • 重载:同一个类中(不一定是在类中),定义了多个同名的函数,这些函数的参数列表(参数个数,参数类类型)不完全相同,这是函数的重载。函数的返回值类型不能作为是否是重载的判断依据,因为返回值类型可以舍弃、可以自动转换等。
  • 重写:类的继承里,子类里含有与父类里同名的虚函数,函数名、函数返回值类型和参数列表必须相同,权限可以不同。如果返回值类型或者参数列表不同,这是子类方法的重定义,即使加了virtual也不会体现出多态。
  • 重定义:父类和子类中有相同名称的非虚函数,返回值类型、参数列表可以不同。子类对象调用该同名方法时,子类方法将覆盖父类方法。

程序1:方法的重载

class A
{
public:
    A(){}
    ~A(){}
    int getMax(int a,int b){return a>b?a:b;}//1
    double getMax(int a,int b){return a>b?a:b;}//2
    double getMax(double a,double b){return a>b?a:b;}//3
};

上面的程序中,方法1和方法3是函数的重载(参数列表不同);但是方法2不是,因为与方法1比起来只是返回值不同,而返回值不能作为函数重载的判断,在编译阶段会出错。

程序2:方法的重定义

class A
{
public:
    A(){}
    ~A(){}
    void show(){cout<<"A::show()"<<endl;}
};

class B:public A
{
public:
    B(){}
    ~B(){}
    void show(){cout<<"B::show()"<<endl;}
};

int main()
{
    A *a = new A();
    B *b = new B();
    A *c = new B();
    a->show();
    b->show();
    c->show();

    system("pause");
    return 0;
}

这里写图片描述
上面的程序中,show()是普通的成员函数,子类B重新定义了show(),因此b->show()的结果是“B::show()”。如果B中没有重新定义show(),那b->show()的结果是“A::show()”。在类的多态中,基类指针c可以指向子类对象,由于show()不是虚函数,因此调用show时将执行指针本身的类型的show(),即A::show()。
如果我修改B中show()的返回值类型或者参数列表:

class B:public A
{
public:
    B(){}
    ~B(){}
    int show(int a){cout<<"B::show()"<<endl; return 1;}
};

那么下面程序中b->show()将报错,因为b中show覆盖了A中的show方法。
这里写图片描述

程序3:方法的重写

class A
{
public:
    A(){}
    ~A(){}
    virtual void show(){cout<<"A::show()"<<endl;}
    virtual void print(){cout<<"A::print()"<<endl;}
    virtual void eat(){cout<<"A::eat()"<<endl;}
};

class B:public A
{
public:
    B(){}
    ~B(){}
    virtual void show(){cout<<"B::show()"<<endl; }
    virtual int print(){cout<<"B::print()"<<endl;}
    virtual void eat(int a){cout<<"B::eat()"<<endl;}
};

上面程序定义了基类A和子类B,并且定义了3个虚函数show(), print() 和eat()。

  • show():是重写,返回类型、参数列表相同;
  • print():不是重写,返回类型不同;
  • eat():是不是重写??反正基类指针派生类对象时,不会调用派生类的eat()方法。
    删掉两个类里面的print()方法定义,运行下面程序:
int main()
{
    A *c = new B();
    c->show();
    c->eat();

    system("pause");
    return 0;
}

这里写图片描述
可以看到,show函数是虚函数,并且在A和B中返回值类型、参数列表相同,是重写,体现了类的多态。而eat函数虽然也是虚函数,但是并没有调用“指向对象的类型”的方法。

猜你喜欢

转载自blog.csdn.net/sinat_21107433/article/details/81663708
今日推荐