zoukankan      html  css  js  c++  java
  • C++ 重载(overload)、重写(overrride)、重定义(redefine)总结

    引自:http://www.189works.com/article-42111-1.html

    先来看几个概念:

    重载(overload),重写(override,也称覆盖), 重定义(redefine,也称隐藏)

    (PS:第三个我不确定在英文中是否应该称为redefine,如有问题,留言告知,谢谢)

    一、重载(overload)
    指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断
    (1)相同的范围(在同一个作用域中) ;
    (2)函数名字相同;
    (3)参数不同;
    (4)virtual 关键字可有可无。
    (5)返回值可以不同;

    问题

    哪个可以是double add(int a,int b)的重载函数?

     

    ABC吧,不能光凭借返回值的类型来判定。

    二、重写(也称为覆盖 override)
    是指派生类重新定义基类的虚函数,特征是:
    (1)不在同一个作用域(分别位于派生类与基类) ;
    (2)函数名字相同;
    (3)参数相同;
    (4)基类函数必须有 virtual 关键字,不能有 static 。
    (5)返回值相同(或是协变),否则报错;<—-协变这个概念我也是第一次才知道…

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

    三、重定义(也成隐藏)
    (1)不在同一个作用域(分别位于派生类与基类) ;
    (2)函数名字相同;
    (3)返回值可以不同;
    (4)参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载以及覆盖混淆) 。
    (5)参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆) 。

    OK,这里给出一个样例代码,是论坛那个问题的代码做了一些修改,方便理解:

     1 #include 
     2 #include 
     3 using namespace std;
     4 
     5 class Base
     6 {
     7 public:
     8     virtual void a(int x)    {    cout << "Base::a(int)" << endl;      }
     9     // overload the Base::a(int) function
    10     virtual void a(double x) {    cout << "Base::a(double)" << endl;   }
    11     virtual void b(int x)    {    cout << "Base::b(int)" << endl;      }
    12     void c(int x)            {    cout << "Base::c(int)" << endl;      }
    13 };
    14 
    15 class Derived : public Base
    16 {
    17 public:
    18     // redefine the Base::a() function
    19     void a(complex<double> x)   {    cout << "Derived::a(complex)" << endl;      }
    20     // override the Base::b(int) function
    21     void b(int x)               {    cout << "Derived::b(int)" << endl;          }
    22     // redefine the Base::c() function
    23     void c(int x)               {    cout << "Derived::c(int)" << endl;          }
    24 };
    25 
    26 int main()
    27 {
    28     Base b;
    29     Derived d;
    30     Base* pb = new Derived;
    31     // ----------------------------------- //
    32     b.a(1.0);                              // Base::a(double)
    33     d.a(1.0);                              // Derived::a(complex)
    34     pb->a(1.0);                            // Base::a(double), This is redefine the Base::a() function
    35     // pb->a(complex(1.0, 2.0));   // clear the annotation and have a try
    36     // ----------------------------------- //
    37     b.b(10);                               // Base::b(int)
    38     d.b(10);                               // Derived::b(int)
    39     pb->b(10);                             // Derived::b(int), This is the virtual function
    40     // ----------------------------------- //
    41     delete pb;
    42 
    43     return 0;
    44 } 
    通过这里可以看出:

    1.Base类中的第二个函数a是对第一个的重载

    2.Derived类中的函数b是对Base类中函数b的重写,即使用了虚函数特性。

    3.Derived类中的函数a是对Base泪中函数a的隐藏,即重定义了。

    4.pb指针是一个指向Base类型的指针,但是它实际指向了一个Derived的空间,这里对pd调用函数的处理(多态性)取决于是否重写(虚函数特性)了函数,若没有,则依然调用基类。

    5.只有在通过基类指针或基类引用 间接指向派生类类型时多态性才会起作用。

    6.因为Base类的函数c没有定义为virtual虚函数,所以Derived类的函数c是对Base::c()的重定义。

  • 相关阅读:
    @RequestParam注解使用:Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
    cglib动态代理导致注解丢失问题及如何修改注解允许被继承
    springboot Autowired BeanNotOfRequiredTypeException
    git根据用户过滤提交记录
    不同包下,相同数据结构的两个类进行转换
    How to use Jackson to deserialise an array of objects
    jooq实践
    java如何寻找main函数对应的类
    Python--matplotlib
    Python 和 Scikit-Learn
  • 原文地址:https://www.cnblogs.com/fickleness/p/3343102.html
Copyright © 2011-2022 走看看