函数重载细说

  在C++语言中,同一范围内相同名称的不同声明称为重载,只有函数声明可以重载,对象或类型声明都不能重载。那是不是所有满足签名相同的函数就一定可以被重载呢?

一、函数重载适用范围

  必须在同一范围(scope),比如同一命名空间或类中。不同命名空间或类中的同名函数不能称为函数重载。下面通过代码进行验证。

  不同命名空间:

 1 namespace A {
 2     void Func(int a, int b)
 3     {
 4 
 5     }
 6 
 7     int Func(int a, int b) // Compile Error, redefinition
 8     {
 9 
10     }
11 }
12 
13 namespace B {
14     void Func(int a, int b)
15     {
16 
17     }
18 }

       

  编译失败,提示命名空间A中的函数重定义了。但是命名空间B没有出现编译提示重定义。

  不同类中:

 1 class ClassA
 2 {
 3 public:
 4     void Method()
 5     {
 6 
 7     }
 8 
 9     int Method() // Compile Error, redefinition.
10     {
11 
12     }
13     
14 };
15 
16 class ClassB
17 {
18     void Method()
19     {
20 
21     }
22 };

  

   类似命名空间,提示ClassA范围函数重复定义,但是ClassB没有报错。

二、函数不能重载的情况

  命名空间或全局空间范围:

  1.仅仅函数返回类型不同,不可重载:

 1 namespace A {
 2     void Func(int a, int b)
 3     {
 4     }
 5 
 6     int Func(int a, int b)
 7     {
 8         return a + b;
 9     }
10 }

  

  2.参数是指针类型和数组类型且相同,不可重载:

 1 namespace A {
 2     void Func(int* b)
 3     {
 4     }
 5 
 6     void Func(int arr[])
 7     {
 8 
 9     }
10 }

  

   因为编译器会将数组类型的转换为指针类型处理,所以不能作为函数重载。

  3.参数指向同一函数地址,不可重载:

1 namespace A {
2     void Func(int())
3     {}
4 
5     void Func(int(*)())
6     {}
7 }

  

   4.参数以值传递的方式并被const和volatile修饰,不可重载:

1 namespace A {
2     void Func(const int x)       // 值传递
3     {}
4 
5     void Func(volatile int x)    // 值传递
6     {}
7 }

  

   如果是引用传递或指针传递,const和volatile,可以被重载:

 1 namespace A {
 2     void Func(const int* ptr)
 3     {}
 4 
 5     void Func(int* const ptr)
 6     {}
 7 
 8     /*void Func(const int* const ptr)  // void Func(const int* ptr) Redefinition
 9     {}*/
10 
11     void Func(volatile int* ptr)
12     {}
13 
14     void Func(int& value)
15     {}
16 
17     void Func(const int& value)
18     {}
19 
20     //void Func(int& const value)     // void Func(const int& value) Redefinition
21     //{}
22 
23     void Func(volatile int& value)
24     {}
25 }

  5.仅仅是默认参数个数不同,不可重载:

 1 namespace A {
 2     void Func(int a, int b)
 3     {}
 4 
 5     void Func(int a, int b = 10)
 6     {}
 7 
 8     void Func(int a = 10, int b = 10)
 9     {}
10 }

  

   类范围,除了上面几种情况外,还涉及到成员函数是静态还是非静态,是const还是非const的:

  1.成员函数名称和参数相同,不管是静态还是非静态成员函数,不可重载:

 1 class ClassA
 2 {
 3 public:
 4     static void Method()
 5     {}
 6 
 7     void Method()
 8     {
 9     }
10 };

  

   2.成员函数名称和参数相同,不管是否被const或volatile修饰,不可重载:

 1 class ClassA
 2 {
 3 public:
 4     static void Method()
 5     {}
 6 
 7     void Method()
 8     {}
 9 
10     void Method() const
11     {}
12 
13     void Method() volatile
14     {}
15 };

  

 三、总结

  谈论函数重载,必须是同一范围内,函数签名相同,参数个数或类型不同。同学们不光要知道函数重载的一般形式,也要知道函数不可重载的情况,方便日后编写代码或看其他人编写代码的时候能知其然。

参考:

C++ International Standard (open-std.org)

posted @ 2021-06-24 23:43  blackstar666  阅读(582)  评论(0编辑  收藏  举报