C++中const用于函数重载
C++中const用于函数重载
常成员函数和非常成员函数之间的重载
首先先回忆一下常成员函数
声明:<类型标志符>函数名(参数表)const;
说明:
(1)const是函数类型的一部分,在实现部分也要带该关键字。
(2)const关键字可以用于对重载函数的区分。
(3)常成员函数不能更新类的成员变量,也不能调用该类中没有用const修饰的成员函数,只能调用常成员函数。
(4)非常量对象也可以调用常成员函数,但是如果有重载的非常成员函数则会调用非常成员函数。
重载看例子:
#include<iostream>
using namespace std; class Test
{
protected:
int x;
public:
Test (int i):x(i) { }
void fun() const
{
cout << "fun() const called " << endl;
}
void fun()
{
cout << "fun() called " << endl;
}
}; int main()
{
Test t1 ();
const Test t2 ();
t1.fun();
t2.fun();
return ;
}
结果为:

const修饰成员函数时的重载
分两种情况,一种情况下不允许重载,另一种允许。还是直接看例子吧:
#include<iostream>
using namespace std; void fun(const int i)
{
cout << "fun(const int) called ";
}
void fun(int i)
{
cout << "fun(int ) called " ;
}
int main()
{
const int i = ;
fun(i);
return ;
}
结果:编译错误,提示重定义:

其实很好理解:
void fun(int a)和
void fun(const int a);
实际上没有区别,因为函数调用的时候,存在形实结合的过程,所以不管有没有const都不会改变实参的值。
但是看下面的情况:
#include<iostream>
using namespace std; void fun(char *a)
{
cout << "non-const fun() " << a;
} void fun(const char *a)
{
cout << "const fun() " << a;
} int main()
{
const char *ptr = "hello world";
fun(ptr);
return ;
}
结果:通过编译,且输出结果为:

很奇怪是吗,这种情况和上面的情况难道不一样吗?
先别急,再来看一个例子。然后再解释。
#include<iostream>
using namespace std; void fun(char *a)
{
cout << "non-const fun() " << a;
} void fun(char * const a)
{
cout << "const fun() " << a;
} int main()
{
char ptr[] = "hello world";
fun(ptr);
return ;
}
结果:编译不通过,提示重定义:

好了,现在解释原因。
第一个例子中,我们说,fun(int i)和fun(const int i)是一样的,是因为函数调用中存在实参和形参的结合。加入我们用的实参是int a,那么这两个函数都不会改变a的值,这两个函数对于a来说是没有任何区别的,所以不能通过编译,提示重定义。
好了,那 fun(char *a)和fun(const char *a)是一样的吗?答案是:不一样。因为char *a 中a指向的是一个字符串变量,而const char *a指向的是一个字符串常量,所以当参数为字符串常量时,调用第二个函数,而当函数是字符串变量时,调用第一个函数。
但是char *a和char * const a,这两个都是指向字符串变量,不同的是char *a是指针变量 而char *const a是指针常量,这就和int i和const int i的关系一样了,所以也会提示重定义。
最后说一下,对于引用,比如int &i 和const int & i 也是可以重载的,原因是第一个i引用的是一个变量,而第二个i引用的是一个常量,两者是不一样的,类似于上面的指向变量的指针的指向常量的指针。
下面是例子:
#include<iostream>
using namespace std; void fun(const int &i)
{
cout << "fun(const int &) called "<<endl;
}
void fun(int &i)
{
cout << "fun(int &) called "<<endl ;
}
int main()
{
const int i = ;
fun(i);
return ;
}
结果为:

最后谢谢,水草的专栏
http://blog.csdn.net/shltsh/article/details/45939977
感谢分享
如果你觉得对你有用,请赞一个吧~~~
C++中const用于函数重载的更多相关文章
- C++中const在函数中的用法
1.const放在函数前面 如果我们的函数的返回值是以 指针形式 返回的,如果在函数前面加上const修饰,则表示指针指向的内容是不能被改变的,并且接收返回值的 指针变量必须是const修饰的,例如: ...
- python中不需要函数重载的原因
函数重载主要是为了解决两个问题: 1.可变参数类型 2.可变参数个数 并且函数重载一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两个函 ...
- php中的__call()函数重载
<?php #调用类中没有的方法时, 会自动调用__call方法重载 #第一个参数是调用时的方法名, 第二个参数为参数组成的数组 class Cat{ public function Hello ...
- C++对c中函数的拓展,函数重载
函数参数的拓展 inline内联函数 最好 小的函数都写成内联函数, 写上inline 编译器不一定内联, C++中推荐使用内联函数替代宏代码片段 C++中使用inline关键字声明内联函数 内联函数 ...
- js中的函数重载
函数重载与js 什么是函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数.类型或者顺序)必须不同,也就是说用 ...
- C++中const关键字的使用方法,烦透了一遍一遍的搜,总结一下,加深印象!!!
之前一直在学习C/C++,关于const的使用,这里出现一点,那里出现一点.知识用时方恨少,这一段时间正好各种笔试题,其中关于const的用法也是层出不穷,所以疲于在书本上各种翻,这里汇总一下,加深自 ...
- C++ 函数重载,函数模板和函数模板重载,选择哪一个?
重载解析 在C++中,对于函数重载.函数模板和函数模板重载,C++需要有一个良好的策略,去选择调用哪一个函数定义(尤其是多个参数时),这个过程称为重载解析. (这个过程将会非常复杂,但愿不要遇到一定要 ...
- C++之const类成员变量,const成员函数
const修饰类的成员函数 const修饰变量一般有两种方式:const T *a,或者 T const *a,这两者都是一样的,主要看const位于*的左边还是右边,这里不再赘述,主要来看一下当co ...
- C++的const成员函数
我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误.例如, const char blank = ‘’; blank = ‘\n’; // 错误 面向对象 ...
随机推荐
- 初识SVN-版本控制工具
慕课网安装教程链接:http://www.imooc.com/video/1924
- java二分查找详解
二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表 ...
- 6.28 Windows Serviece
描述: A 软件,已经注册了一个windows服务并启用,现在需要在服务自己的一个类B里增加一个字段,服务的作用是返回一个该类型B的实例 做法 增加字段,替换服务文件,重新注册服务并开启,但是在A软件 ...
- wcf 上传文件报413,404和发布错误
上传文件错误: 其实要修改所有的服务,不管是服务端还是客户端,Binding那边增加一个没有设置名字的默认配置就OK了: <binding closeTimeout="00:10 ...
- hashMap遍历方式
package Ch17; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java ...
- MySQL问题总结(持续更新)
CHAR和VARCHAR的区别 存储方式和检索方式不同: 1.CHAR固定长度字符类型.CHAR存储定长数据,CHAR字段上的索引效率高,比如定义char(10),那么不论你存储的数据是否达到了10个 ...
- 车牌识别OCR—易泊时代智慧城市解决方案模块
牌识别(License Plate Recognition,LPR) 是视频图像识别技术在智能交通领域中的一个模块.车牌识别运用OCR技术,将视频流或图片中的汽车牌照从复杂的应用场景中提取并识别出来, ...
- [转]Java7中的ForkJoin并发框架初探(中)——JDK中实现简要分析
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp85 根据前文描述的Doug Lea的理论基础,在JDK1.7中已经给 ...
- HDU 6200 2017沈阳网络赛 树上区间更新,求和
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6200 题意:给个图,有2种操作,一种是加一条无向边,二是查询u,v之间必须有的边的条数,所谓必须有的边 ...
- 【.net 深呼吸】WPF 中的父子窗口
与 WinForm 不同,WPF 并没有 MDI 窗口,但 WPF 的窗口之间是可以存在“父子”关系的. 我们会发现,Window 类公开了一个属性叫 Owner,这个属性是可读可写的,从名字上我们也 ...