关于const用法的学习
被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设计书籍建议:“Use const whenever you need”。
1、const作函数参数
例如函数
void addTeacher(Teacher t);
如果是值传递,这样会使程序的效率降低,因为值传递过程中函数入口的参数是临时变量,用于复制主函数中函数调用传来的值,这个过程中临时变量的构造、复制、析构等过程都需要消耗时间,所以这个时候就考虑引用传递,如下:
void addTeacher(Teacher &t);
因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象,所以提升了程序的效率。但是函数参数引用存在一个缺点,在函数“引用传递”时可能改变参数t的内容,正因如此,所以这个时候就可以通过添加const关键字去完善,如下:
void addTeacher(const Teacher &t);
注意:对于某些内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如voidFunc(int x) 不应该改为voidFunc(const int &x)。
2、const作函数的返回值
如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。例如函数
const char * GetString();
如下语句将出现编译错误:
char *str = GetString();
正确的用法是
const char *str =GetString();
如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。例如不要把函数intGetInt(void) 写成constint GetInt(void)。如果返回值不是内部数据类型,将函数AGetA(void) 改写为constA &GetA(void)的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了,否则程序会出错。函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。例如:
class A
{
public:
A(char c){
this->x=c;
}
A & operator =(const A a){
cout<<"Test "<<x<<"="<<a.x<<endl;
}
private:
char x;
};
int main(){
A a('a'), b('b'), c('c'); // a, b, c 为A的对象
a = b = c; // 正常的链式赋值
( a = b ) = c ;// 不正常的链式赋值,但合法
}
如果将赋值函数的返回值加const修饰
const A & operator =(const A a){
cout<<"Test "<<x<<"="<<a.x<<endl;
}
那么该返回值的内容不允许被改动。上例中,语句a= b = c 仍然正确,但是语句(a= b) = c 则是非法的。(a=b=c中,的执行顺序是b=c,a=b;而(a=b)=c的执行顺序是a=b,a=c,即试图修改a的值)。
3、成员函数
const成员函数的声明看起来怪怪的:const关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。
任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。如下程序将会报错,
class A
{
public:
A(char c){
this->x=c;
}
A & operator =(const A a){
cout<<"Test "<<x<<"="<<a.x<<endl;
}
void print() const{
cout<<"x(value): "<<x<<endl;
x='y';
}
private:
char x;
};
4、mutable
如果现在,我们要在上述代码中增添一个功能:计算每个对象的输出次数。如果用来计数的变量是普通的变量的话,那么在const成员函数print()里面是不能修改该变量的值的;所以应该为了修改该变量而去掉其附加的const属性。这个时候,就该我们的mutable出场了——只要用mutalbe来修饰这个变量,所有问题就迎刃而解了。代码如下:
class A
{
public:
A(char c){
this->x=c;
count=0;
}
const A & operator =(const A a){
cout<<"Test "<<x<<"="<<a.x<<endl;
}
void print() const {
count++;
cout<<"x(value): "<<x<<" count:"<<count<<endl;
}
private:
char x;
mutable int count;
};
int main(){
A a('a');
a.print();
a.print();
}
关于Const函数的几点规则:
a.const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
b.const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
c.const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查.
d.然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的
本文部分转载自:https://blog.csdn.net/zcf1002797280/article/details/7816977
关于const用法的学习的更多相关文章
- c++ const用法小结
const用法 1,定义全局变量的内存分配问题 #define Pi_1 3.14 //使用#define宏 const double Pi_2 = 3.14 //使用const ...
- const用法
一.const作用 二.const用法 1.修饰一般常量 修饰符const可以用在类型说明符前,也可以用在类型说明符后. 例如: ; ; 2.修饰常数组 修饰符const可以用在类型说明符前,也 ...
- #define中 #与##的神奇用法linux学习 (转)
#define中 #与##的神奇用法linux学习 (转) #define f(a,b) a##b #define d(a) #a #define s(a) d(a) void main( void ...
- 【转】话说C语言const用法
原文:话说C语言const用法 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修 ...
- static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符
一.static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝 C++ Code 1 2 3 4 5 6 7 8 9 10 11 ...
- const用法详解(转)
http://www.cnblogs.com/StudyRush/archive/2010/10/06/1844690.html 面向对象是C++的重要特性. 但是c++在c的基础上新增加的几点优化也 ...
- 重载和const形参的学习心得
在C++ primer 5th中,第6章的练习6.39(a)中,关于重载和const形参的学习心得. 练习6.39:说明在下面的每组声明中第二条声明语句是何含义.如果有非法的声明,请指出来. (a) ...
- C++之常指针,指针常量,函数指针,const用法总结
1.const char *p,char const *p,char * const p 对于C++而言,没有const * 修饰符,所以,const只可以修饰类型或者变量名.因而const char ...
- C++学习之路—const用法总结
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) C++为什么要引入const?它允许你指定一个语 ...
随机推荐
- vue.js中内联样式style三元表达式
<span v-bind:style="{'display':config.isHaveSearch ? 'block':'none'}" >搜索</span&g ...
- MQ消息队列在软件开发中的作中
MQ的作用是非常之大的. 1.解耦. 当一个大型的系统.比如,商城系统.包括以下的功能: 1.发邮件 2.发短信 3.抽奖 4.搜索等 如果你都用一台服务器,做到一个程序里,代码会非常庞大,不利于维护 ...
- centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总
centos平台基于snort.barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总 原创 2016年12月19日 01:20:03 标签: centos / snort ...
- CentOS 使用yum命令安装出现错误提示”could not retrieve mirrorlist http://mirrorlist.centos.org ***”
执行yum命令时出现以上错误; 解决方法: vi /etc/sysconfig/network-scripts/ifcfg-eth0 这一段为你的网卡修改图中框框部分 然后重启 :reboot
- boost asio 学习(七) 网络基础 连接器和接收器(TCP示例)
http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=8 7. Net ...
- 使用Shell脚本对Linux系统和进程资源进行监控
ShellLinux脚本 摘要:Shell语言对于接触Linux的人来说都比较熟悉,它是系统的用户界面,提供了用户与内核进行交互操作的一种接口.本文我们以Bash做为实例总结了使用Shell对系统和进 ...
- 我的idea突然没有SVN了是怎么回事
总结一下没有svn选项的几种情况: 情况1:IntelliJ IDEA打开带SVN信息的项目不显示SVN信息,项目右键SVN以及图标还有Changes都不显示解决方法 在VCS菜单中有个开关,叫Ena ...
- Win7 VS2015 NASM汇编语言环境配置
参考了以下两个博客文章 http://blog.csdn.net/x356982611/article/details/51260841 http://www.cnblogs.com/antonioz ...
- 判断终端类型、微信的文章防盗链、h5页面跳转打开新的app、跳转到app市场
判断终端的类型.安卓.ios.微信.qq function GetMobelType() { var browser = { ...
- 巧用 Jersey RESTful WebService框架解决文件上传乱码
一.当我们使用jersey框架封装的restful进行文件上传时,会出现中文乱码,试用了过滤器设置编码都不管用.仔细想了很久解决办法,就用一个servelt来代替这个上传的restful接口实现上传的 ...