C++重载与重写的各种问题
2016-09-12 11:10
288 查看
C++重载与重写的各种问题
知识复习
在探究C++虚函数造成的各种重写的问题之前,我们先复习一下C++中的函数重载1.const在函数重载中的定义
对于下几种情况,哪几个算是函数重载呢?//情况1 void fun(int a); void fun(const int a); //情况2 void fun(int* a); void fun(const* a); //情况3 void fun(int* a) void fun(int const * a); //情况4 void fun(int *a) void fun(int *const a);
答案是:2,3是函数重载,1,4是重定义
情况1
我们可以假设这样的调用情况fun(1)
那么对于第一种定义,我们可以看到
int a=1
是可以的,而第二种定义
const int a=1
同样也没问题,所以这里我们也就可以理解这里为什么是重定义了
情况2
我们可以假设这样的调用情况const int b=1;fun(&b);
那么对于第一种定义,我们可以看到
int* a=&b
是不可以的,因为
const int*是不可以向
int *装换的,而第二种定义
const int* a=&b
毫无问题,所以我们可以通过这种方法将两种方法区分出来,那么传入
int*调用的是那种呢?是第一种,因为,第一种显然更匹配一些。
情况3
哈哈,const int *和
int const *是等价的,所以如同情况2一样
情况4
这种情况就和情况1类似,这里就不多做解释了总结
在C++中,函数重载还是重定义靠的是,是否有一种调用情况能将两种函数区分开来,如果能就是重载,否则就是重定义。const在重载与重写中的作用
我们考虑这样的情况,以下两个函数哪个是重载,哪个是重写?class A { public: void test_const(int a) { } void test_const_function(int a) { } }; class B:public A { public: //情况1 void test_const(int a) { } //情况2 void test_const_function(int a) const { } }
答案是情况1是重写,情况2是重载
情况1
这个很简单,相当于上边的情况1,因为我们无法区分调用在传入相同参数调用哪个函数,所以是重定义,但是用在虚函数上边就变成了重写。情况2
但这是为什么呢?其实是因为在类里边
void test_const_function(int a) { } | | |会被改写成 | v void test_const_function(A&a,int a) { } void test_const_function(int a) const { } | | |会被改写成 | v void test_const_function(const A&a,int a) { }
那么就变成了上边情况2,所以变成了重载,重写失败。
默认参数在重载与重写中的作用
情况如下,那些会调用成功呢?class A { void test_default_parament(int a,int b=4) { cout<<"A:"<<a<<" B:"<<b<<endl; } } class B:public A { void test_default_parament(int a=0,int b=0) { cout<<"A:"<<a<<" B:"<<b<<endl; } } int main() { B* bpoint=new B A* apoint=bpointer; //情况1 apoint-> test_default_parament(1,2); //情况2 apoint-> test_default_parament(1); //情况3 apoint-> test_default_parament(); }
答案是情况1和情况2,情况3会被认为缺少参数
分析
根本原因是默认参数时静态绑定的apoint-> test_default_parament(1); | | | V apoint-> test_default_parament(1,4) //绑定父类的默认参数 apoint-> test_default_parament(1); | | | V apoint-> test_default_parament(1,0) //绑定子类函数的默认参数
说以略微思考一下,就可以知道为什么上边会调用失败了吧,更深一步,我们也可以知道函数具体输出的结果
总结
最好的方法是,不要在虚函数中使用默认参数,如果我们真的想用怎么办呢,世界之大,方法总会有的么。private,public在重载与重写中的作用
有以下几种情况,哪几种会调用成功呢?class A { public: virtual void Test_public() { cout<<"father"<<endl; } private: virtual void Test_private() { cout<<"father"<<endl; } }; class B:public A { public: virtual const int Test_private() { } private: virtual void Test_public() { } }; int main() { B* bpointer=new B; A* apointer=bpointer; bpointer->Test_private(); bpointer->Test_public(); apointer->Test_public(); apointer->Test_private(); return 0; }
嘿嘿,这里不给出答案了,比较难打,但是代码写的比较全,各位可以运行一下
为什么呢?其实本质这里也是一样的,对于操作权限都是静态绑定的
总结
函数权限,默认参数都是静态绑定的函数重载和重定义都是依靠是否能有一种调用情况区分调用函数的
相关文章推荐
- C语言异常处理的方式
- C++学习笔记(字符串string、vector_deque、queue,multiset、map、multimap、容器拷贝问题)(复制粘贴,方便后面翻阅)
- error LNK2019: unresolved external symbol
- c++ 前置声明
- 《C++ Primer》Page400,对容器元素重新排序的算法
- 图像增强方法之 直方图均衡化 (的原理)
- C语言常见类型占用字节数
- 4000 Poedu_C语言_20160912_复习
- 文件复制(c语言)
- C/C++中volatile关键字详解
- VC++库函数PathRemoveFileSpec() 使用说明
- C++里的抽象类和纯虚函数
- C++中几种将整数转换成二进制输出的方法总结
- 【VSCode】Windows下VSCode编译调试c/c++
- C/C++实现八大排序算法汇总
- C++宏定义详解
- C++文件操作详解(ifstream、ofstream、fstream)
- (转)c/c++内存对齐问题
- C/C++一些零碎的知识
- 使用C语言对单向链表的操作