overload,override,overwrite小结

overload,override,overwrite小结

这几个关键字本身没有多大联系,但是因为名字上的关系,造成了一些误解,其次C++里面也没有overwrite这一说法,对应的概念应该为覆盖重写。

overload

同一个作用域中,定义了多个函数名完全相同、参数(类型或者个数)不相同的函数

如何解决命名冲突?
根据“作用域+返回类型+函数名+参数列表” 做name tangling。作用域指的是在一个类中定义了不同的重载函数,类本身就标识了一个作用域。

不同的编译器有不同的名字修饰规则,因此很少有链接器能够处理所有编译器产生的目标代码。

名字修饰还有一个很常见的点,在C++代码里面经常看到下面代码,这是为了保证条件编译的代码段按照C语言处理,即不做名字修饰。

如果不加extern C,对下面的一些C库函数做了名字修饰,那么在C runtime libaray将导致链接错误

1
2
3
4
5
6
7
8
9
10
11
12
#ifdef __cplusplus
extern "C" {
#endif

void *memset (void *, int, size_t);
char *strcat (char *, const char *);
int strcmp (const char *, const char *);
char *strcpy (char *, const char *);

#ifdef __cplusplus
}
#endif

什么函数不能够被重载?

  1. 仅仅返回类型不同,不能够做函数重载
  2. 成员函数名称以及参数完全相同,仅仅其中一个是static成员函数。
  3. 函数参数差别仅在于有无顶层const或volatile

注意,用const 修饰的成员函数是重载, 因为const 用来修饰成员函数中隐含的this 指针

这里就引入什么是top-level const/volatile

A top-level const qualifier affects the object itself. Others are only relevant with pointers and references.

char const x = 't';就是顶层常量

override 可能存在二义性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//转型造成二义性
void function(float);
void function(int);
function(3.4);// 转型 C++中浮点数为double
function(34);

//默认形参带来的二义性v
void function(int);
void function(int,int);
void function(int x)
{
std::cout << "Value of x is : " <<x<< std::endl;
}
void function(int y,int z=12)
{
std::cout << "Value of y is : " <<y<< std::endl;
std::cout << "Value of z is : " <<z<< std::endl;
}

2.override

子类重新改写父类声明为virtual的函数
有几个特点:

  • 范围不同(作用域不同)

  • 函数签名完全一样(名字,常数列表)

  • 基类函数必须带有virtual 关键字

    C++11 中的 override关键字,可以显式的在派生类中声明,哪些成员函数需要被重写,如果没被重写,则编译阶段会报错

3.overwrite

派生类的函数隐藏了与其同名的基类函数 ,两种情况

  • 派生类函数参数与基类不同,不管基类有无virtual
  • 派生类函数参数与基类相同,但是基类没有virtual

overwrite 是要被避免的,其行为不是我们预期的,C++11 引入override 关键字就是起这个作用的

参考

override keyword’s function

名字修饰

extern c/c++