【C++ 】重载和重写

重载和重写的区别

  1. 重写

    是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类对象调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有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类中重写 
}
  1. 重载

术语"函数重载"指的是可以有多个同名的函数,因此对名称进行了重载。这两个术语指的是同一回事,但我们通常使用函数重载。可以通过函数重载来设计一系列函数—它们完成相同的工作,但使用不同的参数列表。

#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语言显现函数重载,可通过以下方式来实现:

  1. 使用函数指针来实现,重载的函数不能使用同名称,只是类似的实现了函数重载功能
  2. 重载函数使用可变参数,方式如打开文件open函数
  3. gcc有内置函数,程序使用编译函数可以实现函数重载
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值