C++函数名字的隐藏:重写、重载、重定义

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

概要:

C++中经常出现函数名字一样,但参数列表或返回值不同的函数,要搞清楚函数的正确调用关系,需理清三个概念:重写(override)、重载(overload)、重定义(redefine)。

一、三个基本概念

1、重定义(redefine):派生类对基类的成员函数重新定义,即派生类定义了某个函数,该函数的名字与基类中的函数名字一样。

特点:(1)不在同一个作用域(分别位于基类、派生类)(2)函数的名字必须相同(3)对函数的返回值、形参列表无要求

特殊情况:若派生类定义的该函数与基类的成员函数完全一样(返回值、形参列表均相同),且基类的该函数为virtual,则属于派生类重写基类的虚函数。

作用效果:若重新定义了基类中的一个重载函数,则在派生类中,基类中该名字的函数(即其他所有重载版本)都被自动隐藏,包括同名的虚函数。

2、重载(overload):函数名字相同,但它的形参个数或者顺序,或者类型不同,但是不能靠返回类型来判断。

特点:(1)位于同一个类中(2)函数的名字必须相同(3)形参列表不同(可能是参数个数 or 类型 or 顺序不同),返回值无要求

特殊情况:若某一个重载版本的函数前面有virtual修饰,则表示它是虚函数。但它也是属于重载的一个版本

不同的构造函数(无参构造、有参构造、拷贝构造)是重载的应用

作用效果和原理:编译器根据函数不同的参数表,将函数体与函数调用进行早绑定。重载与多态无关,只是一种语言特性,与面向对象无关。

3、重写(override):派生类重定义基类的虚函数,即会覆盖基类的虚函

数(多态性)

特点:(1)不在同一个作用域(分别位于基类、派生类)(2)函数名、形参列表、返回值相同(3)基类的函数是virtual

特殊情况:若派生类重写的虚函数属于一个重载版本,则该重写的函数会隐藏基类中与虚函数同名的其他函数。

作用效果:父类的指针或引用根据传递给它的子类地址或引用,动态地调用属于子类的该函数。这个晚绑定过程只对virtual函数起作用

具体原理是由虚函数表(VTABLE)决定的,在第三节介绍。

二、程序实例

1、两个类:基类(取名Test)和派生类(取名XX)名字不规范,哈哈随便取得!

基类和派生类的结构

//Base class

class Test

{

public:

int a;

Test()

{

cout<<"Test() 无参构造函数!"<

}

Test(int data)

{

a = data;

cout<<"Test(int data) 有参构造函数!"<

}

Test(const Test &tmp)

{

a = tmp.a;

cout<<"Test 拷贝构造函数!!"<

}

//基类中对函数名f,进行了重载。其中最后一个重载函数为虚函数

void f()const

{

cout<<"调用 void Test::f()"<

}

//overload

int f(int data) const

{

cout<<"调用 Test f(int data)"<

return1;

}

//overload 虚函数

virtual double f(int dataA,int dataB)

{

cout<<"调用 Test f(int a,int b)"<

return dataA*dataB/2.0;

}

};

class XX: public Test

{

public:

Test atest;//先调用基类的构造函数,然后对象成员的构造函数,最后才是派生类的构造函数

XX()

{

cout<<"XX() 无参构造函数被调用!"<

}

//对基类的函数名f,进行了重定义。则会隐藏基类中的其他f函数

//redefine

int f() const

{

cout<<" 调用 XX f()函数"<

return1;

}

//重写基类的虚函数

//redefine override

double f(int dataA,int dataB)

{

cout<<"调用 XX f(int dataA,int dataB)函数"<

return (dataA+dataB)/2.0;

}

};

分析:基类class Test中定义了名为f的3个重载函数,其中最后一个是虚函数

派生类class XX中对f进行了重定义,所以会隐藏基类中名为f的版本。其中派生类的double f(int dataA,int dataB)属于对虚函数的重写

测试---主程序

int main()

{

//-----test 1------------------------

cout<<"-------test 1------------"<

//Base class

Test aaTest;

aaTest.f();

aaTest.f(12);

aaTest.f(10,20);

//derived class

XX d;

d.f();

// d.f(2); //error C2661: 'f' : no overloaded function takes 1 parameters

d.f(10,20);

//--------test 2----------------------------------

cout<<"-------test 2------------"<

Test b = d;

b.f();

b.f(10,20);//调用的是基类的函数,不发生多态

//--------test 3----------------------------------------

cout<<"-------test 3------------"<

Test &bR = d;//引用

b.f();//f()不是虚函数,调用基类的函数

bR.f(10,20);//调用的是派生类的函数,发生多态

//--------test 4--------------------------------------

cout<<"-------test 4------------"<

Test* pB = &d;

b.f();

pB->f(10,20);//调用的是派生类的函数,发生多态

相关文档
最新文档