关于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?它允许你指定一个语 ...
随机推荐
- mybatis-plus 自动生成代码
public class MpGenerator { /** * <p> * MySQL 生成演示 * </p> */ public static void main(Stri ...
- Zookeeper 集群配置及启动
准备工作 1. 集群机器 192.168.8.2 192.168.8.6 192.168.8.11 2. 包 zookeeper-3.4.10.tar.gz 集群配置 1. 解压路径 192.168. ...
- The best way to use Xtool X100 PAD2 for FEM programming
Look here: XTOOL X100 PAD2 is new FEM programming. Possible to use Xtool X100 PAD2 for FEM programmi ...
- Zookeeper Client基础操作和Java调用
## Zookeeper > Zookeeper目前用来做数据同步,再各个服务之前同步关键信息 i.客户端操作 1. 创建 create [-s] [-e] path data acl -s 为 ...
- jedis set 的四个重载方法(byte[]的四个自动忽略)
方法定义如下: 1.String set(String key, String value) 2.String set(String key, String value, String nxxx) 3 ...
- Linux 下查看我们的不速之客
我们通过下面这个命令,可以查看 VPS 上还有谁在登陆: w 输出类似下列信息: 23:20:00 up 960 days, 4:29, 2 user, load average: 0.05, 0.0 ...
- 单片机之PID算法
说到PID算法,想必大部人并不陌生,PID算法在很多方面都有重要应用,比如电机的速度控制,恒温槽的温度控制,四轴飞行器的平衡控制等等,作为闭环控制系统中的一种重要算法,其优点和可实现性都成为人们的首选 ...
- scala字符串前加s使用$
https://my.oschina.net/u/2000675/blog/1592140 字符串中的变量替换,Scala中基础的字符串插值就是在字符串前加字幕‘s’,然后在字符串中放入变量,每个变量 ...
- MySQL与SQL语句的操作
MySQL与SQL语句的操作 Mysql比较轻量化,企业用的是Oracle,基本的是熟悉对数据库,数据表,字段,记录的更新与修改 1. mysql基本信息 特殊数据库:information_sche ...
- 库函数wordcloud安装的问题
在对python有了一定的了解之后就对python的第三方库产生了十分浓厚的兴趣,因为python的很多功能都是要依靠第三方库函数来实现的,而且在计算机二级刚刚加入的python考试中也有对第三方库的 ...