关于C++重载、重写、重定义的理解

关于C++重载、重写、重定义的理解

三个名词的定义

重载:(overload)是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型,即返回类型可以相同或不同。

重写(覆盖):(override)是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

重载和重写的区别:

(1)范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中。
(2)参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同。
(3)virtual的区别:重写的基类必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有。

隐藏和重写,重载的区别:
(1)与重载范围不同:隐藏函数和被隐藏函数在不同类中。
(2)参数的区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定同;当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写。

正常情况下的重载

class A{
public:
  void test(int i);
  void test(double i);        //overload
  void test(int i, double j); //overload
  void test(double i, int j); //overload
  int test(int i);            //错误,非重载。注意重载不关心函数返回类型。
};

之前说到重载的三个条件,类型、顺序或个数不相同,只要满足一个就可以说是重载吗?显然,类型或个数不同时肯定可以算是重载的,下面考虑仅顺序不同的情况。

class A{
public:
  void test(int a, int b);
  void test(int b, int a); //不是重载
};

test(int a, int b)和test(int b, int a)仅顺序不同,但是参数类型相同,这不能算做重载,实验如下:
#include 

using namespace std;

class A{
public:
  void test(int a, int b)
  {
	  cout << a+b << endl;
	  cout << "test(int a, int b)" << endl;
  }
  void test(int b, int a) //不是重载
  {
	  cout << a+b << endl;
	  cout << "test(int b, int a)" << endl;
  }
};

int main() {
	cout << "hello world" << endl;
	return 0;
}

运行结果,编译无法通过。

/code/main.cpp:12:8: error: ‘void A::test(int, int)’ cannot be overloaded
  void test(int b, int a) //不是重载
        ^
/code/main.cpp:7:8: error: with ‘void A::test(int, int)’
  void test(int a, int b)

总的来说,辨别是否是重载函数,在于两个同名函数是否能通过参数进行区分,或者说是否能唯一辨识,避免出现二义性。

你可能感兴趣的:(C/C++)