重载和重写的区别
-
重写
是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类对象调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。
#include<bits/stdc++.h>
using namespace std;
class A {
public:
virtual void fun()
{
cout << "A";
}
};
class B :public A
{
public:
virtual void fun()
{
cout << "B";
}
};
int main(void)
{
A* a = new B();
a->fun();//输出B,A类中的fun在B类中重写
}
- 重载
术语"函数重载"指的是可以有多个同名的函数,因此对名称进行了重载。这两个术语指的是同一回事,但我们通常使用函数重载。可以通过函数重载来设计一系列函数—它们完成相同的工作,但使用不同的参数列表。
#include<bits/stdc++.h>
using namespace std;
class A {
void fun() {};
void fun(int i) {};
void fun(int i, int j) {};
void fun1(int i,int j){};
};
重载实现
函数重载的关键是函数的参数列表——也称为函数特征标(function signature)。如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。C++允许定义名称相同的函数,条件是它们的特征标不同。如果参数数目和/或参数类型不同,则特征标也不同。
使用被重载的函数时,需要在函数调用中使用正确的参数类型。
匹配函数时,并不区分 const 和非 const 变量。
void dribble(char *bits); // overloaded
void dribble (const char *cbits); // overloaded
void dabble(char * bits);// not overloaded
void drivel(const char * bits);// not overloaded
下面列出了各种函数调用对应的原型∶
const char pl[20]="How's the weather?";
char p2[20] = "How's business?";
dribble(p1); // dribble(const char *);
dribble(p2); // dribble(char *);
dabble(p1); // no match
dabble(p2); // dabble(char *);
drivel(p1); // drivel(const char *);
drivel(p2); // drivel (const char *);
是特征标,而不是函数类型使得可以对函数进行重载,返回类型可以不同,但特征标也必须不同∶
long gronk(int n,float m); // different signatures,
double gronk (float n,float m);// hence allowed
使用 C++开发工具中的编辑器编写
和编译程序时,C++编译器将执行一些神奇的操作———名称修饰(name decoration)或名称矫正(name mangling),它根据函数原型中指定的形参类型对每个函数名进行加密。请看下述未经修饰的函数原型∶
long MyFunctionFoo(int, float);
这种格式对于人类来说很适合;我们知道函数接受两个参数(一个为 int类型,另一个为 float 类型),并返回一个long 值。而编译器将名称转换为不太好看的内部表示,来描述该接口,如下所示∶
?MyFunctionFoo@@YAXH
对原始名称进行的表面看来无意义的修饰(或矫正,因人而异)将对参数数目和类型进行编码。添加的一组符号随函数特征标而异,而修饰时使用的约定随编译器而异。名称矫正是在编译阶段完成的。
重写操作的实现
在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。
- 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
- 存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
- 多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。
- 重写用虚函数来实现,结合动态绑定。
- 纯虚函数是虚函数再加上 = 0。
- 抽象类是指包括至少一个纯虚函数的类。
纯虚函数:virtual void fun()=0。即抽象类必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容。
C 语言实现 C++ 语言中的重载
c语言中不允许有同名函数,因为编译时函数命名是一样的,不像c++会添加参数类型和返回类型作为函数编译后的名称,进而实现重载。如果要用c语言显现函数重载,可通过以下方式来实现:
- 使用函数指针来实现,重载的函数不能使用同名称,只是类似的实现了函数重载功能
- 重载函数使用可变参数,方式如打开文件open函数
- gcc有内置函数,程序使用编译函数可以实现函数重载