C++函数前和函数后加const修饰符区别
class Test(){
public:
Test(){}
const int foo(int a);
const int foo(int a) const;
};
一、概念
当const在函数名前面的时候修饰的是函数返回值。
当const在函数名后面表示是常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。
二、原理:
我们都知道在调用成员函数的时候编译器会将对象自身的地址作为隐藏参数传递给函数,在const成员函数中,既不能改变this所指向的对象,也不能改变this所保存的地址,this的类型是一个指向const类型对象的const指针。
c++中关于const的用法有很多,const既可以修饰变量,也可以函数,不同的环境下,是有不同的含义。今天来讲讲const加在函数前和函数后面的区别。比如:
#include<iostream> using namespace std; // Ahthor: 过往记忆
// E-mail: wyphao.2007@163.com
// Blog: http://www.iteblog.com
// 转载请注明出处 class TestClass {
public:
size_t length() const;
const char* getPContent();
void setLengthValid(bool isLengthValid);
private:
char *pContent;
size_t contentLength; //A
bool lengthIsValid; //B
size_t precontentLength;
}; size_t TestClass::length() const{ //函数名后加const
if(!lengthIsValid){
contentLength= strlen(pContent); //C
lengthIsValid = true; //D
} return contentLength;
} const char* TestClass::getPContent(){//函数名前加const
return pContent;
} void TestClass::setLengthValid(bool isLengthValid){
lengthIsValid = isLengthValid;
} int main(void){
TestClass *tc =new TestClass;
tc->setLengthValid(false);
tc->length();
char * content = tc->getPContent(); //E
return ;
}
其中类TestClass中的length函数和getPContent函数分别在函数名后和前加了const修饰符,如果试图编译上面的代码,将会得到下面的错误:
--------------------配置: mingw5 - CUI Debug, 编译器类型: MinGW--------------------
检查文件依赖性...
正在编译 C:\Users\wyp\Desktop\未命名1.cpp...
[Error] C:\Users\wyp\Desktop\未命名1.cpp:: error: assignment of data-member `TestClass::contentLength' in read-only structure
[Error] C:\Users\wyp\Desktop\未命名1.cpp:: error: assignment of data-member `TestClass::lengthIsValid' in read-only structure
[Error] C:\Users\wyp\Desktop\未命名1.cpp:: error: invalid conversion from `const char*' to `char*'
[Warning] C:\Users\wyp\Desktop\未命名1.cpp::: warning: no newline at end of file 构建中止 未命名1: 个错误, 个警告
里面有三个错误,也就是代码C、D、E处的三个地方。为什么C和D处的代码会出错,原因如下:
length函数名的后面加了const修饰符,这样说明函数的成员对象是不允许修改的。我们都知道,在类的成员函数里面,默认是在成员函数的第一个位置是this指针,如果在成员函数(只能是成员函数,要是类的静态函数或者是非成员函数就不可以在函数名后面加上const)后面const,则说明this指针的值是不可以修改的,只能读取。而上面的length函数可能会修改里面的contentLength和lengthIsValid的值,这样编译器肯定是不允许的,所以这样是会出现错误的。
解决方法是:在类的A、B处的成员前面加上mutable修饰符:
mutable size_t contentLength; //A
mutable bool lengthIsValid; //B
从字面的意思知道,mutalbe是“可变的,易变的”,跟constant(既C++中的const)是反义词。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。这样在C、D处将不会出错。
那么,为什么E处出现了错误。这是因为在函数名getPContent前加了const修饰符,意味着该函数返回的值只能是读取,而不能被修改。而E处的content却为char *是可以被修改的,这与const正好相反了,所以出现了错误。解决方法是:在char *前面加上const修饰符,即:
const char * content = tc->getPContent(); //E
再去编译运行,这样就不会出现错误了。
C++函数前和函数后加const修饰符区别的更多相关文章
- [Reprint]C++函数前和函数后加const修饰符区别
c++中关于const的用法有很多,const既可以修饰变量,也可以函数,不同的环境下,是有不同的含义.今天来讲讲const加在函数前和函数后面的区别.比如: 01 #include<iostr ...
- C++ 成员函数前和函数后加const修饰符区别
博客转载自: https://www.iteblog.com/archives/214.html 分析以下一段程序,阐述成员函数后缀const 和 成员函数前const 的作用 #include< ...
- 函数后面的const修饰符的作用
比如 void Fun() const; 的const是修饰什么的? 其实是修饰this指向的对象的. 这篇文章很详细的说明了const的作用,其中第三点说明了这种const的作用:const的用法, ...
- const修饰符限定的常量
类型前加const修饰符限定变量为只读,称为常量,定义时必须初始化,且初始化后编译器不允许再修改常量的值. 一.常量的定义 const在类型前面 const int value: //value是co ...
- C++中的const成员函数(函数声明后加const,或称常量成员函数)用法详解
http://blog.csdn.net/gmstart/article/details/7046140 在C++的类定义里面,可以看到类似下面的定义: 01 class List { 02 priv ...
- 【VS开发】【C++开发】const在函数前与函数后的区别
const在函数前与函数后的区别 一 const基础 如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况: int b = ...
- C++: C++函数声明的时候后面加const
C++: C++函数声明的时候后面加const 转自:http://blog.csdn.net/zhangss415/article/details/7998123 非静态成员函数后面加const(加 ...
- const修饰符与函数
一.用const修饰函数的参数 函数参数类型前加const指明该参数为常量,在函数内部不可改变. void func(const int x) { //x不可以在内部进行赋值等操作. } 注:当参数为 ...
- Delphi 中 函数参数中的 const 修饰符的本质以及注意事项
来自:http://blog.csdn.net/farrellcn/article/details/9096787 ------------------------------------------ ...
随机推荐
- LDA-math-MCMC 和 Gibbs Sampling
http://cos.name/2013/01/lda-math-mcmc-and-gibbs-sampling/ 3.1 随机模拟 随机模拟(或者统计模拟)方法有一个很酷的别名是蒙特卡罗方法(Mon ...
- Oracle中的rownum用法解析
注意:rownum从1开始: 1.rownum按照记录插入时的顺序给记录排序,所以有order by的子句时一定要注意啊! 2.使用时rownum,order by字段是否为主键有什么影响? 3 ...
- 操作系统—Systemd
操作系统-Systemd 时间 2016-09-24 22:34:49 运维部落 原文 http://www.178linux.com/48990 主题 systemd Systemd 概述: C ...
- linux主机vps简单性能测试
第一,CPU.内存.硬盘检测 cat /proc/cpuinfo (查看CPU信息) cat /proc/meminfo (查看内存信息) df -lh (查看硬盘信息) 这个命令可以看到我们购买的V ...
- 【python cookbook】【数据结构与算法】18.将名称映射到序列的元素中
问题:希望通过名称来访问元素,减少结构中对位置的依赖性 解决方案:使用命名元组collections.namedtuple().它是一个工厂方法,返回的是python中标准元组类型的子类,提供给它一个 ...
- XML 解析 -- IE ,Chrome
通用的method <script type="text/javascript"> //for chrome, attach method to XMLDocument ...
- session 加入redis的实现代码方式
session,中文经常翻译为会话,其本来的含义是 指有始有终的一系列动作/消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session.有时候我们可以看到这样的话&quo ...
- PHP无限级分类-递归(不推荐)
[http://www.helloweba.com/view-blog-204.html] 在一些复杂的系统中,要求对信息栏目进行无限级的分类,以增强系统的灵活性.那么PHP是如何实现无限级分类的呢? ...
- Android中的图片压缩
1.android中计算图片占用堆内存的kB大小跟图片本身的kB大小无关,而是根据图片的尺寸来计算的. 比如一张 480*320大小的图片占用的堆内存大小为: 480*320*4/1024=600kB ...
- python :生产者和消费者模型 即简单的协程
def consumer(name): print('%s开始准备吃包子了' %name) while True: baozi=yield print('[%s]包子来了,被[%s]吃了' %(bao ...