博客转载自: https://www.iteblog.com/archives/214.html

分析以下一段程序,阐述成员函数后缀const 和 成员函数前const 的作用

#include<iostream>

using namespace std;

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修饰符,如果试图编译上面的代码,将会得到下面的错误:

里面有三个错误,也就是代码C、D、E处的三个地方。为什么C和D处的代码会出错,原因如下
length函数名的后面加了const修饰符,这样说明函数的成员对象是不允许修改的。我们都知道,在类的成员函数里面,默认是在成员函数的第一个位置是this指针,如果在成员函数(只能是成员函数,要是类的静态函数或者是非成员函数就不可以在函数名后面加上const)后面const,则说明this指针的值是不可以修改的,只能读取。而上面的length函数可能会修改里面的contentLength和lengthIsValid的值,这样编译器肯定是不允许的,所以这样是会出现错误的。
解决方法是:在类的A、B处的成员前面加上mutable修饰符:

mutable size_t contentLength;
mutable bool lengthIsValid;

从字面的意思知道,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修饰符区别的更多相关文章

  1. [Reprint]C++函数前和函数后加const修饰符区别

    c++中关于const的用法有很多,const既可以修饰变量,也可以函数,不同的环境下,是有不同的含义.今天来讲讲const加在函数前和函数后面的区别.比如: 01 #include<iostr ...

  2. C++函数前和函数后加const修饰符区别

    class Test(){ public: Test(){} const int foo(int a); const int foo(int a) const; }; 一.概念 当const在函数名前 ...

  3. 函数后面的const修饰符的作用

    比如 void Fun() const; 的const是修饰什么的? 其实是修饰this指向的对象的. 这篇文章很详细的说明了const的作用,其中第三点说明了这种const的作用:const的用法, ...

  4. C++中的const成员函数(函数声明后加const,或称常量成员函数)用法详解

    http://blog.csdn.net/gmstart/article/details/7046140 在C++的类定义里面,可以看到类似下面的定义: 01 class List { 02 priv ...

  5. 【VS开发】【C++开发】const在函数前与函数后的区别

    const在函数前与函数后的区别 一   const基础           如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况:           int   b   =   ...

  6. C++: C++函数声明的时候后面加const

    C++: C++函数声明的时候后面加const 转自:http://blog.csdn.net/zhangss415/article/details/7998123 非静态成员函数后面加const(加 ...

  7. const修饰符与函数

    一.用const修饰函数的参数 函数参数类型前加const指明该参数为常量,在函数内部不可改变. void func(const int x) { //x不可以在内部进行赋值等操作. } 注:当参数为 ...

  8. Delphi 中 函数参数中的 const 修饰符的本质以及注意事项

    来自:http://blog.csdn.net/farrellcn/article/details/9096787 ------------------------------------------ ...

  9. 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体

    1.字符串输出输入函数 读入字符串的方法: 1) scanf 特点:不能接收空格 2) gets 特点:可以接受含有空格的字符串 ,不安全 3) fgets(); 特点:可以帮我们自动根据数组的长度截 ...

随机推荐

  1. Django - Ajax分页

    目前总结了2种方法: 1. Ajax 分页 尼玛各种google,stackoverflow,搞了好久才总结出这个,之前使用Pagination tag loading的方式不好用,并且不能进行aja ...

  2. MAMP mac下启动Mysql

    MAMP mac下启动Mysql /Applications/MAMP/Library/bin/mysql -u root -p 初始密码 root:

  3. poj1321

    这个题要是乍一看很难会想深搜,确实如此,可如果知道了深搜的方法,这个题就简 了不少,至于用深搜的时候要考虑当k==n和k<n时这咱种情况,当K==n时,当然很好想 到深搜搜下很容易找到所有方法, ...

  4. Java演示手机发送短信验证码功能实现

    我们这里采用阿里大于的短信API 第一步:登陆阿里大于,下载阿里大于的SDK a.在阿里大于上创建自己的应用 b.点击配置管理中的验证码,先添加签名,再配置短信模板 第二步:解压相关SDK,第一个为j ...

  5. [转]NME Android目标中文输入问题完美解决!

    最近研究了一下haxe,发现蛮牛逼的,转几篇知识帖 haXe开发笔记:中文问题的小结 * .hx源文件中如果包含中文,要保存成UTF-8编码才能够正确被haXe编译器解析,是否包含BOM(Byte O ...

  6. 如何在IJ中使用Jaxb2通过xml定义生成对应的Java Entity类的文件

    #0. 准备要转换的xml文件,在Project视界中,右击这个xml文件,在弹出的菜单上选择“Generate XSD schema from XML File...”, 按默认设置生成xsd文件. ...

  7. Angular5学习笔记 - 创建服务(九)

    一.创建服务 ng generate service service-name #简写 ng g s component-name ng g s services/userService 二.效果 三 ...

  8. Spring Boot 集成Swagger2生成RESTful API文档

    Swagger2可以在写代码的同时生成对应的RESTful API文档,方便开发人员参考,另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API. 使用Spring Boot可 ...

  9. eclipse下不能编译.ftl文件,会报错的解决方法

    先安装一个插件 右击ftl文件,选择open with 但是没有freeMarker这个选项,如果有直接打开,如果没有则需要下载相关插件. 要安装一个freemarker的插件,才可以编辑FTL文件, ...

  10. java代码输入流篇2

    总结: 方法.和之前的有不同,但是名字太长了+++++ package com.aini; import java.io.*; public class ghd { public static voi ...