zoukankan      html  css  js  c++  java
  • 重载 覆盖 隐藏

    【1】重载

    (1)重载是指在同一个类内被声明的几个具有不同参数列的同名函数。

    函数名必须相同,不考虑函数的返回值类型。

    (2)示例代码如下:

     1 #include <iostream>
     2 using  namespace std;
     3 
     4 class Sample
     5 {
     6 public:
     7     void  Func(int a, char ch)       // 原函数
     8     {
     9         cout << "a " << a << "  " << "ch " << ch << endl;
    10     }
    11     void  Func(char ch, int a)   // 重载1:参数顺序不同
    12     {
    13         cout << "ch " << ch << " " << "a " << a << endl;
    14     }
    15     void  Func(int a)           // 重载2:参数个数不同
    16     {
    17         cout << "a  " << a << endl;    
    18     }
    19     void  Func(int a, double db) // 重载3:参数类型不同
    20     {
    21         cout << "a " << a << " " << "db " << db << endl;
    22     }
    23     void  Func(int a, char ch) const      // 重载4:常函数(被const修饰的函数)
    24     {
    25         cout << "a " << a << "  " << "ch " << ch << endl;
    26     }
    27     /*
    28     int Func(int a, char ch)      // error! 非重载,编译无法通过。因为编译器认为是重定义。
    29     {
    30         cout << "a" << a << "  " << "ch" << endl;
    31         return a;
    32     }
    33     */
    34 };
    35 
    36 void main()
    37 {
    38     Sample ss;
    39     ss.Func(10, 'a');
    40     ss.Func('a', 20);
    41     ss.Func(30);
    42     ss.Func(40, 12.34);
    43     system("pause");
    44 }
    45 
    46 // 运行结果:
    47 /*
    48 a 10  ch a
    49 ch a a 20
    50 a  30
    51 a 40 db 12.34
    52 请按任意键继续. . .
    53 */

    分析总结:

    <1> 在同一个类中(同一作用域中)。

    <2> 方法名相同。

    <3> 参数个数、参数类型或者参数顺序不同。

    <4> 与函数的返回值类型无关。

    如果仅仅返回值类型不同,那么对编译器来说会在调用时产生二义性。

    所以,抛开返回值类型再分析即相当于重定义,重定义是被禁止的(一个函数只允许有一份函数体)。

    <5> const修饰。类中成员函数,const 用在函数后一般修饰的是this指针。所以,也算重载的范畴。

    【2】覆盖

    (1)覆盖也叫重写,是指在派生类中重写基类某虚函数的实现体的一种形式。

    函数名、参数列表、返回值类型都必须同基类被重写的虚函数的严格一致。

    仅仅只是函数实现体不同。即达到严格的覆盖目的。

    (2)示例代码如下:

     1 #include <iostream>
     2 using  namespace std;
     3 
     4 class Sample
     5 {
     6 public:
     7     virtual void Func()
     8     {
     9         cout << "Sample::Func" << endl;
    10     }
    11 };
    12 
    13 class  Test : public Sample
    14 {
    15 public:
    16     void Func()
    17     {
    18         cout << "Test::Func" << endl;
    19     }
    20 };
    21 
    22 void  main()
    23 {
    24      Sample* pa = new Test();
    25      pa->Func();
    26      delete pa;
    27      pa = NULL;
    28      system("pause");
    29 }
    30 /* run out:
    31 Test::Func
    32 请按任意键继续. . .
    33 */

    分析总结:

    <1> 不同的范围(分别位于基类和派生类,不同作用域中)。

    <2> 方法名相同。

    <3> 参数严格一致。

    <4> 返回类型相同。

    <5> 基类函数前必须要加关键字virtual,即必须是虚函数。

    【3】隐藏

    (1)隐藏是指在派生类中隐藏基类的同名函数。

    与重载范围不同,隐藏函数和被隐藏函数不在同一个类中。

    与覆盖条件不同,隐藏函数和被隐藏函数的参数可以相同,也可以不同,但是函数名必须要相同。

    重要备注

    <1> 当参数相同时,如果基类中的函数被virtual修饰,基类的函数就是所谓被覆盖。

    <2> 当参数相同时,如果基类中的函数没有被virtual修饰,基类的函数就是所谓被隐藏。

    <3> 当参数不相同时,无论基类中的函数是否被virtua修饰,基类的函数都是所谓的被隐藏。

    (2)示例代码如下:

      1 #include <iostream>
      2 using namespace std;
      3 
      4 class Sample
      5 {
      6 public:
      7     virtual void Func0()
      8     {
      9         cout << "Sample::Func0" << endl;
     10     }
     11 
     12     virtual void Func1()
     13     {
     14         cout << "Sample::Func1" << endl;
     15     }
     16 
     17     void Func2(int a)
     18     {
     19         cout << "Sample::Func2" << endl;
     20     }
     21 
     22     void Func3(const char *db)
     23     {
     24         cout << "Sample::Func3" << endl;
     25     }
     26 
     27     void Func4(int n, int m)
     28     {
     29         cout << "Sample::Func4" << endl;
     30     }
     31 };
     32 
     33 class Test : public Sample
     34 {
     35 public:
     36     // 覆盖
     37     void Func0()  // 带virtual关键字,参数相同
     38     {
     39         cout << "Test::Func0" << endl;
     40     }
     41     // 隐藏1
     42     void Func1(int a)   // 带virtual关键字,参数不同
     43     {
     44         cout << "Test::Func1" << endl;
     45     }
     46 
     47 #if 0
     48     int Func1()   // 带virtual关键字,参数相同,但返回值不同
     49     {
     50         cout << "Test::Func1_R" << endl;
     51         return 0;
     52     }
     53     // -- E0317    返回类型与重写虚拟函数 "Sample::Func1" 的返回类型 "void" 既不相同,也不协变
     54 #endif
     55 
     56     // 隐藏2
     57     void Func2(int a)   // 不带virtual,参数相同,返回值相同
     58     {
     59         cout << "Test::Func2" << endl;
     60     }
     61 
     62 #if 0
     63     int Func2(int a)   // 不带virtual,参数相同,但返回值不同
     64     {
     65         cout << "Test::Func2_R" << endl;
     66         return 0;
     67     }
     68     // -- E0311    无法重载仅按返回类型区分的函数
     69 #endif
     70 
     71     // 隐藏3
     72     void Func3(int a)   // 不带virtual,参数不同,返回值相同
     73     {
     74         cout << "Test::Func3" << endl;
     75     }
     76     // 隐藏4
     77     int Func4(double dn, double dm) // 不带virtual,参数不同, 返回值不同
     78     {
     79         cout << "Test::Func4" << endl;
     80         return 0;
     81     }
     82 };
     83 
     84 int main()
     85 {
     86     Test t1;
     87     t1.Func0();  // Test::Func0 
     88 //  t1.Func1();  // error! 被隐藏,无法调用
     89     t1.Func1(10); // Test::Func1
     90     t1.Func2(20); // Test::Func2
     91 
     92     const char *str = "kaizen";
     93 //  t1.Func3(str);  // error! 被隐藏,无法调用
     94     t1.Func3(30);   // Test::Func3
     95     t1.Func4(10, 20); // Test::Func4
     96     cout << endl;
     97 
     98     Sample* pSamp = new Test();
     99     pSamp->Func0(); // Test::Func0
    100     pSamp->Func1(); // Sample::Func1
    101     pSamp->Func2(200); // Sample::Func2
    102     pSamp->Func3(str); // Sample::Func3
    103     pSamp->Func4(100, 200); // Sample::Func4
    104     delete pSamp;
    105     pSamp = NULL;
    106     cout << endl;
    107 
    108     Test* pTest = new Test();
    109     pTest->Func0(); // Test::Func0
    110 //  pTest->Func1();  // error! 参数不匹配
    111     pTest->Func2(200); // Test::Func2
    112 //  pTest->Func3(str);  // error! 参数不匹配
    113     pTest->Func4(100, 200); // Test::Func4
    114     delete pTest;
    115     pTest = NULL;
    116 
    117     system("pause");
    118 
    119     return 0;
    120 }
    121 // run out:
    122 /*
    123 Test::Func0
    124 Test::Func1
    125 Test::Func2
    126 Test::Func3
    127 Test::Func4
    128 
    129 Test::Func0
    130 Sample::Func1
    131 Sample::Func2
    132 Sample::Func3
    133 Sample::Func4
    134 
    135 Test::Func0
    136 Test::Func2
    137 Test::Func4
    138 请按任意键继续. . .
    139 */

    分析总结:

    <1> 不同的范围(分别位于基类和派生类,不同作用域)。

    <2> 方法名相同。

    <3> 有关键字virtual,必须要参数不同。

    <4> 无关键字virtual,参数任意。

    <5> 图解

    【4】总结

    三者的关系,总结为一张图:

    Good Good Study, Day Day Up.

    顺序 选择 循环 总结

    作者:kaizen
    声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
    签名:顺序 选择 循环
  • 相关阅读:
    圣战 [奇环, 树上差分]
    花火之声不闻于耳 [线段树]
    SP2878 KNIGHTS
    P5300 [GXOI/GZOI2019]与或和 [单调栈]
    Speike [线段树, 动态规划]
    Jerry [动态规划]
    JSON对象
    正则书写
    flex布局实践
    数组对象的深拷贝与浅拷贝
  • 原文地址:https://www.cnblogs.com/Braveliu/p/2843255.html
Copyright © 2011-2022 走看看