C++ 重载、重写、重定义的区别

C++ 中 重载、重写、重定义的区别

重载(overload)

定义:

在同一个作用域内,两函数的函数名相同, 参数不相同(可以是参数类型不同或者是参数个数不同), 那么就说这两个 函数重载

分类:函数重载 和 运算符重载 (本质都一样)

注意: 返回值类型 不是 函数重载判断依据。

成员函数重载特征:

a : 相同的范围(在同一个类中)

b : 函数名字相同

c : 参数不同

实现重载原理:

C++代码在编译时会根据参数列表对函数进行重命名,例如void Test(int a, int b)会被重命名为_Test_int_int,void Test(int x, double y)会被重命名为_Test_int_double。所以说函数重载从底层上看它们还是不同的函数。

例:

#include<iostream>
using namespace std;
void fun(int a)
{
   cout << "int a" << endl;
}
void fun(double a)
{
   cout << "double a" << endl;; 
}
void fun(int a, int b)
{
   cout << "int a , int b" << endl;;
}
int main()
{
    //函数名相同,参数不同
    fun(1);
    fun(1.1);
    fun(1,2);
}

输出结果:

int a

double a

int a , int b

重写(override)

定义:

重写也叫做覆盖。子类 重新定义 父类中 有相同名称和参数虚函数。函数特征相同,但是具体实现不同,主要是在继承关系中出现的 。简单说,重写(覆盖) 是指 派生类函数覆盖基类函数

注意:

  1. 被重写的函数不能是 static 的。必须是 **virtual **的。

  2. 重写函数必须有 相同的类型,名称和参数列表

  3. 重写函数的访问修饰符可以不同。尽管virtual是private的,派生类中重写改写为public,protected也是可以的

特征:

a : 不同的范围,分别位于基类和派生类中

b : 函数的名字相同

c : 参数相同

d : 基类函数必须有virtual关键字

作用:

通过重写,可以实现动态多态,何为动态多态,就是当父类的指针或引用指向被重写的虚函数时,父类的指针或引用指向谁就调用谁的虚函数,而不是说根据类型。
在这里,如果去掉父类的虚函数的virtual,则构不成多态,如果去掉子类虚函数的virtual可以构成多态,可以理解为编译器优化。

重定义(redefining)

定义:重定义也叫做隐藏。子类 重新定义 父类中有 相同名称非虚函数 ( 参数列表可以不同 ) 。也就是说,重定义(隐藏) 是指 派生类的函数屏蔽了与其同名的基类函数

规则:

a : 如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无virtual,基类的函数被隐藏。

b : 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有 vitual 关键字,此时,基类的函数被隐藏。

例:

#include<iostream>
using namespace std;
class A{
public:
    void f()
    {
        cout << "A" << endl;
    }

public:
    int _x;
};

class B : public A{
public:
    void f(int a)
    {
        cout << "B" << endl;
    }

public:
    int _x;
};

int main()
{
    B b;
    b.f();
}

分析:

很明显,子类隐藏了父类的f函数,这个题目比较迷惑人的是子类的f函数有参数,所以会以为调的是父类的f函数; 但是隐藏只与函数名有关,与参数是没关系的,所以调用的还是子类的f函数,这个程序会提示出错(可能是没有匹配的重载函数之类的错误)。

posted @ 2020-11-27 15:54  FreeK0x00  阅读(413)  评论(0编辑  收藏  举报