学习小记--C++--重载与多态--6.04
2013-06-04 22:57
281 查看
最近项目用到了C++,工作也比较轻闲,看了看C++Primer,对C++的重载多态有了更直接了解。
重载是指C++允许在同一模块内存在同名函数,只要他们有不同的参数表,即参数个数或参数类型不同。
但如果只是返回值不同,则是不行的,编译会报错,如下main中的fun()调用就出现二义性,违反了程序设计原则。
重载在C语言中是不被支持的如下
那么C++是如何实现准确定位到相应的重载函数呢?如我在上面的TestDemo.cpp的main中调用fun(1);就会执行void fun(int a)函数。
在C++Primer中有详细介绍,分为三步:
1,找到候选函数,如上面的与fun同名都是候选函数; 如果函数实参的类型是在一个名字空间中被声明的则该名字空间中与被调用函数同名的成员函数也将被视为候选函数。
2,确定可行函数,可行函数是候选函数集合中的函数,它的参数表与调用中的实参数目相同或者有更多的参数,在后一种情况下额外的参数会被给出缺省实参,以便可以用实参表中指定的实参调用该函数。可行函数是这样的函数,对于每个实参,都存在到函数参数表中相应的参数类型之间的转换。上面的情况就可确定为void fun(int a); 与void fun(double b);
3,找到最佳可行函数,最佳可行函数是具有与实参类型匹配最好的参数的可行函数,最佳可行函数是满足下列条件的可行函数:
1 )用在实参上的转换不比调用其他可行函数所需的转换更差。
2 )在某些实参上的转换要比其他可行函数对该参数的转换更好。
这样上面的调用就被确定为fun(int a);
如果第三步不能确定唯一的最佳可行函数,则就会出现二义性,编译不通过,如下面的代码。
多态,就是在不同的子类中同一方法呈现不同特性。C++多态就是在基类的函数前面加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。
强调要实现多态,基类函数名前必需要加virtual,如我们去上面的virtual则运行如下:
就没有达到了多态的效果,这要想执行B 或C的fun只有通过((B*)a)->fun();这样来实现了。
这是为什么呢?virtual到底有什么作用?
因在没有使用virtual前,C++对成员函数使用静态联编;而在使用virtual后,C++对成员函数使用动态联编,是在调用函数时是通过函数指针或引用调用。
http://baike.baidu.com/view/161302.htm虚函数的介绍。
重载是指C++允许在同一模块内存在同名函数,只要他们有不同的参数表,即参数个数或参数类型不同。
//TestDemo.cpp //Author : Wing void fun(){} void fun(int a){} void fun(double d){} int main(){ }
但如果只是返回值不同,则是不行的,编译会报错,如下main中的fun()调用就出现二义性,违反了程序设计原则。
void fun(){} int fun(){} int main(){ fun(); }
重载在C语言中是不被支持的如下
//test.c void fun(){} void fun(int a){}; int main(){ }
那么C++是如何实现准确定位到相应的重载函数呢?如我在上面的TestDemo.cpp的main中调用fun(1);就会执行void fun(int a)函数。
#include <iostream> using namespace std; void fun(){cout<<"fun()"<<endl;} void fun(int a){cout<<"fun(int a)"<<endl;} void fun(double b){cout<<"fun(double b)"<<endl;} int main(){ fun(1); }
在C++Primer中有详细介绍,分为三步:
1,找到候选函数,如上面的与fun同名都是候选函数; 如果函数实参的类型是在一个名字空间中被声明的则该名字空间中与被调用函数同名的成员函数也将被视为候选函数。
2,确定可行函数,可行函数是候选函数集合中的函数,它的参数表与调用中的实参数目相同或者有更多的参数,在后一种情况下额外的参数会被给出缺省实参,以便可以用实参表中指定的实参调用该函数。可行函数是这样的函数,对于每个实参,都存在到函数参数表中相应的参数类型之间的转换。上面的情况就可确定为void fun(int a); 与void fun(double b);
3,找到最佳可行函数,最佳可行函数是具有与实参类型匹配最好的参数的可行函数,最佳可行函数是满足下列条件的可行函数:
1 )用在实参上的转换不比调用其他可行函数所需的转换更差。
2 )在某些实参上的转换要比其他可行函数对该参数的转换更好。
这样上面的调用就被确定为fun(int a);
如果第三步不能确定唯一的最佳可行函数,则就会出现二义性,编译不通过,如下面的代码。
void fun(int a, float f=1.0f){} void fun(int a){} int main(){ fun(1); }
多态,就是在不同的子类中同一方法呈现不同特性。C++多态就是在基类的函数前面加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。
//TestDemo.cpp //Author : Wing #include <iostream> using namespace std; class A{ public: virtual void fun(){cout<<"A fun"<<endl;} }; class B:public A{ public: void fun(){cout<<"B fun"<<endl;} }; class C:public A{ public: void fun(){cout<<"C fun"<<endl;} }; int main(){ A* a = new B; a->fun(); a = new C; a->fun(); }
强调要实现多态,基类函数名前必需要加virtual,如我们去上面的virtual则运行如下:
就没有达到了多态的效果,这要想执行B 或C的fun只有通过((B*)a)->fun();这样来实现了。
这是为什么呢?virtual到底有什么作用?
因在没有使用virtual前,C++对成员函数使用静态联编;而在使用virtual后,C++对成员函数使用动态联编,是在调用函数时是通过函数指针或引用调用。
http://baike.baidu.com/view/161302.htm虚函数的介绍。
相关文章推荐
- C++简单学习(Part2_lecture 8)(继承、重载、多态、虚函数)
- 转---C++学习之多态及重载(overload),覆盖(override),隐藏(hide)的区别
- C++学习之多态及重载(overload),覆盖(override),隐藏(hide)的区别
- C++学习笔记五——函数重载(多态)、函数模板及函数模板重载和完全匹配与最佳匹配
- c++ 学习 对重写(覆盖)、重载、多态的理解
- C++学习之多态及重载(overload),覆盖(override),隐藏(hide)的区别
- C++学习笔记之覆盖、重载、多态的区别
- 详解一道C++笔试题,考察重载、覆盖、多态
- [C++基础]重载、覆盖、多态与函数隐藏(4)
- Java视频学习笔记:基础(五)之多态、重载、覆盖
- c++学习之多态(虚函数和纯虚函数)
- [C++再学习系列] 二元操作符重载
- C++学习之函数重载内幕
- C++学习笔记之 函数重载和函数指针在一起
- 改善C++ 程序的150个建议学习之建议33:小心翼翼地重载operator new/ operator delete
- C++学习笔记-----函数调用时的决议:名字查找,重载决议,可访问性检测
- C++中的重载,覆盖,隐藏与多态
- C++入门学习:多态的概念及其原理
- 高质量c++(重载、多态、隐藏)
- C++ 类的多态(方法的重载与继承)