参考文章:c++三大概念要分清–重载,隐藏(重定义),覆盖(重写)
 
                               
重载
在同一个作用域内
1. 函数名相同
2. 参数列表不同(参数个数不同,或者参数类型不同,或者参数个数和参数类型都不同)
3. 返回值类型可相同也可不同
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 | test_ooh.cpp
 namespace {
 
 int Add(int a, int b)
 {
 PRINT_INFO("int " << __func__ << "(int, int)");
 return a + b;
 }
 
 double Add(double a, double b)
 {
 PRINT_INFO("double " << __func__ << "(double, double)");
 return a + b;
 }
 
 }
 
 class test_ooh
 {
 public:
 test_ooh(){}
 ~test_ooh(){}
 
 int Add(int a, int b)
 {
 PRINT_INFO("int " << "test_ooh::" << __func__ << "(int, int)");
 return a + b;
 }
 
 double Add(double a, double b)
 {
 PRINT_INFO("double " << "test_ooh::" << __func__ << "(double, double)");
 return a + b;
 }
 };
 
 
 Add(1, 2);
 Add(1.2, 3.2);
 
 test_ooh to;
 to.Add(1, 2);
 to.Add(1.3, 2.2);
 
 | 
输出结果:
[INFO]: int Add(int, int)
[INFO]: double Add(double, double)
[INFO]: int test_ooh::Add(int, int)
[INFO]: double test_ooh::Add(double, double)
- 匿名 namespace 下的两个函数 Add() ,在同一作用域,函数名相同,参数类型不同,就构成了 C++ 中的函数重载;
- 调用函数名相同的函数,会根据 实参的类型和实参顺序以及实参个数选择相应的函数;
- C++ 函数重载是一种 静态多态(又叫做静态联编,静态绑定,静态决议)
重写(覆盖)
不在同一个作用域内(分别在父类和子类):
1. 函数名相同
2. 参数列表相同
3. 返回值类型相同(协变除外)
4. 基类函数必须有 virtual 修饰(即虚函数)
5. 父子类中的函数的访问修饰符可以不同
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 
 | test_ooh.cpp
 class Base
 {
 public:
 Base(){}
 ~Base(){}
 
 
 virtual void show()
 {
 PRINT_INFO("Base::show()");
 }
 
 
 virtual Base& getThis()
 {
 PRINT_INFO("Base::getThis()");
 return *this;
 }
 
 };
 
 class Derived : public Base
 {
 public:
 Derived(){}
 ~Derived(){}
 
 
 virtual void show()
 {
 PRINT_INFO("Derived::show()");
 }
 
 
 Derived& getThis()
 {
 PRINT_INFO("Derived::getThis()");
 return *this;
 }
 
 };
 
 
 namespace {
 void callFunc(Base& b)
 {
 b.show();
 b.getThis();
 }
 
 void callFunc(Base* b)
 {
 b->show();
 b->getThis();
 }
 }
 
 Base b;
 Derived d;
 
 callFunc(b);
 callFunc(d);
 callFunc(&b);
 callFunc(&d);
 
 
 | 
输出结果:
[INFO]: Base::show()
[INFO]: Base::getThis()
[INFO]: Derived::show()
[INFO]: Derived::getThis()
[INFO]: Base::show()
[INFO]: Base::getThis()
[INFO]: Derived::show()
[INFO]: Derived::getThis()
- 父类函数为虚函数;
- 当在子类中定义了一个与父类完全相同的虚函数时,则称子类的这个函数重写(也称覆盖)了父类的这个虚函数;(子类中的虚函数和父类中的虚函数,函数名,参数个数,参数类型,返回值类型都相同;这种情况下子类的这个虚函数重写的父类中的虚函数,构成了重写)
- 协变 ——— 是说子类中的虚函数和父类中的虚函数,函数名,参数个数,参数类型都相同,只是返回值类型不同;父类的虚函数返回父类的指针或者引用,子类虚函数返回子类的指针或者引用;这种情况下子类的这个虚函数也重写了父类中的虚函数,也构成了重写;———— 我们把这种特殊的情况叫做协变
重定义(隐藏)
不在同一个作用域内(分别在父类和子类):
1. 函数名相同
2. 在父类和子类中只要不构成重写的都是重定义
3. 重定义的不光是类的成员函数,还可以是类的成员变量
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 
 | test_ooh.cpp
 class Base
 {
 public:
 Base():i_(0){}
 Base(int i):i_(i){}
 ~Base(){}
 
 
 virtual void show()
 {
 PRINT_INFO("Base::show()");
 }
 
 
 virtual Base& getThis()
 {
 PRINT_INFO("Base::getThis()");
 return *this;
 }
 
 
 virtual void test_hiding()
 {
 PRINT_INFO("Base::test_hiding()");
 }
 
 
 void test_show(int a)
 {
 PRINT_INFO("Base::test_show(int) , a = " << a);
 }
 
 
 int test_hiding2()
 {
 PRINT_INFO("Base::test_hiding2()");
 
 return 0;
 }
 
 public:
 int i_;
 
 };
 
 class Derived : public Base
 {
 public:
 Derived(){}
 Derived(int i):Base(i),i_(0){}
 ~Derived(){}
 
 
 virtual void show()
 {
 PRINT_INFO("Derived::show()");
 }
 
 
 Derived& getThis()
 {
 PRINT_INFO("Derived::getThis()");
 return *this;
 }
 
 
 void test_hiding(int a)
 {
 PRINT_INFO("Derived::test_hiding(int) , a = " << a);
 }
 
 
 void test_show(int a, int b)
 {
 PRINT_INFO("Derived::test_show(int) , a = " << a << ",b = " << b);
 }
 
 
 void test_hiding2()
 {
 PRINT_INFO("Derived::test_hiding2()");
 }
 
 public:
 int i_;
 
 };
 
 Base b1;
 Derived d1(1);
 b1.test_hiding();
 d1.Base::test_hiding();
 d1.test_hiding(1);
 
 PRINT_INFO("Derived::i_ = " << d1.i_);
 PRINT_INFO("Base::i_ = " << d1.Base::i_);
 
 b1.test_show(1);
 d1.Base::test_show(1);
 d1.test_show(1, 2);
 
 b1.test_hiding2();
 d1.Base::test_hiding2();
 d1.test_hiding2();
 
 
 | 
输出结果:
[INFO]: Base::test_hiding()
[INFO]: Base::test_hiding()
[INFO]: Derived::test_hiding(int) , a = 1
[INFO]: Derived::i_ = 0
[INFO]: Base::i_ = 1
[INFO]: Base::test_show(int) , a = 1
[INFO]: Base::test_show(int) , a = 1
[INFO]: Derived::test_show(int) , a = 1,b = 2
[INFO]: Base::test_hiding2()
[INFO]: Base::test_hiding2()
[INFO]: Derived::test_hiding2()