1. const修饰变量

int b = 100;
const int* a = &b; //情况1
int const* a = &b; //情况2
int* const a = &b; //情况3
const int* const a = &b; //情况4

const修饰有三种情况:

第一:const在“ * ”左边,则const用来修饰指针所指向的变量,即指针指向为常量,如情况1,情况2;

第二:const在“ * ”右边,则const用来修饰指针本身,即指针本身是常量,如情况3;

第三:const在“ * ”两边,则const既修饰指针本身也修饰指针所指变量,如情况4;

注意:const的相对位置只与“ * ”有关,和变量的类型声明没有位置关系,其次const修饰指针所指变量时可以不初始化,但const修饰指针本身时必须初始化。

2. const在函数中的使用

2.1 const修饰函数的参数

输入参数采用“指针传递”,那么加const修饰可以防止意外的改动该指针指向的内存单元,起到保护作用,如StringCopy函数

//输入参数: strSrc   输出参数:strDest
void StringCopy(char* strDest, const char* strSrc);

如果还想保护指针本身,则可以声明指针本身为常量,例如:

void OutputString(const char* const pStr);

如果参数用于输出,不论它是什么类型,也不论它采用“指针传递”还是“引用传递”,都不能加const修饰,即const只能修饰输入参数。另外如果如果输入参数采用“值传递”,由于函数将自动用实参的拷贝初始化形参,因此即使在函数内部修改了该参数,改变的也只是堆栈上的拷贝而不是实参,所以一般不需要const修饰。最好不要把void Func(const int x)改为void Func(const int &x)这样即达不到提高效率的目的有让人费解。因为基本数据类型的参数不存在构造、析构的过程,除基本类型参数为推荐使用“const &传递”。

2.2 const修饰函数返回值

如果给“指针传递”的函数返回值加const修饰符,那么返回值是一种契约性常量,不能被直接修改,并且该返回值只能被赋值给加const修饰的同类型指针(除非强制转换),例如:

const char* GetString(void);  //函数声明
char* str = GetString(); //编译错误
const char* str = GetString(); //正确

如果函数返回值采用“值传递”的方式,在一般情况下由于函数会把返回值拷贝到外部的临时存储单元中,所以加const修饰是没有什么意义的。

2.3 const成员函数

class CTextBlock
{
public:
...
std::size_t length() const;
private:
char* pText;
std::size_t textLength;
bool lengthIsValid;
};
std::size_t CTextBlock::length() const
{
if(!lengthIsValid)
{
textLength = std::strlen(pText); //错误,const成员函数不能给类中的
lengthIsValid = true; //成员变量赋值
}
return textlength;
}

const成员函数不能给类中的成员变量赋值,如果非得给类中成员变量赋值,可以用mutable来修饰成员变量,如:

mutable std::size_t textLength;
mutable bool lengthIsValid;

3. const与#define比较

第一:const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查而对后者只能进行字符替换,没有安全类型检查,并且替换中可能会出现意料不到的错误(边际效应)。

第二:编译处理宏定义时,在预编译时将实际将所有宏定义全部替换成成实际值然后进行编译,const修饰的值在编译期间的常量,同时const常量可能比define产生更小的代码量。

第三:有些集成化调试工具可以对const常量进行调试,但不能对宏常量进行调试。

第四:#define不能创建一个class专属常量,也不能提供任何封装性,const可以定义class专属常量,如:

class GamePlayer
{
private:
static const int NumTurns = 5;
int scores[NumTurns];
}

建议:对于单纯常量,最好以const对象或enums替换#define;对应形似函数的宏,最好用inline函数替换#define。

补充知识:

C中的const是“一个不能被改变的普通变量”,它总是占用内存,而且它是全局变量,C编译器不能把const看成一个变异期间的常量,在C中下面的函数是不合理的

const bufsize = 100;
char buf[bufsize];

而在C++中是正确的,C默认const是外部连接的,C++默认const是内部连接的

const用法总结的更多相关文章

  1. c++ const用法小结

    const用法 1,定义全局变量的内存分配问题 #define  Pi_1  3.14       //使用#define宏 const double Pi_2 = 3.14    //使用const ...

  2. const用法

    一.const作用 二.const用法 1.修饰一般常量   修饰符const可以用在类型说明符前,也可以用在类型说明符后. 例如: ; ; 2.修饰常数组  修饰符const可以用在类型说明符前,也 ...

  3. 【转】话说C语言const用法

    原文:话说C语言const用法 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修 ...

  4. static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符

    一.static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝  C++ Code  1 2 3 4 5 6 7 8 9 10 11 ...

  5. const用法详解(转)

    http://www.cnblogs.com/StudyRush/archive/2010/10/06/1844690.html 面向对象是C++的重要特性. 但是c++在c的基础上新增加的几点优化也 ...

  6. C++之常指针,指针常量,函数指针,const用法总结

    1.const char *p,char const *p,char * const p 对于C++而言,没有const * 修饰符,所以,const只可以修饰类型或者变量名.因而const char ...

  7. C++的那些事:const用法面面观

    一.const是什么 在 C/C++ 语言中,const关键字是一种修饰符.所谓“修饰符”,就是在编译器进行编译的过程中,给编译器一些“要求”或“提示”,但修饰符本身,并不产生任何实际代码.就 con ...

  8. 【三支火把】---C语言const用法总结

    C语言关键字const相信对于不少C语言新手是既陌生又熟悉的,好像经常见,但是却不知道为何用,怎么用?学习至此,总结一下const的用法,使用程序来帮助你理解该关键字,希望能帮到像我一样的新手. 我看 ...

  9. typedef,static,const用法

    一.typedef主要功能是定义一个已存在类型的别名,但是和宏并存 宏与typedef区别 1.宏定义只是简单的字符串替换 2.typedef定义的类型是类型的别名,typedef后面是一个整体声明, ...

  10. C++中const用法详解

    本文主要内容来自CSDN论坛: http://bbs.csdn.net/topics/310007610 我做了下面几点补充. 补充: 1. 用const声明全局变量时, 该变量仅在本文件内可见, 类 ...

随机推荐

  1. Solr导入数据库数据

    接Solr-4.10.2与Tomcat整合.1.在solrconfig.xml中添加数据导入节点,solrconfig.xml路径为D:\solr\data\solr\collection1\conf ...

  2. ORACLE触发器的管理与实际应用【weber出品】

    一.INSTEAD OF触发器 对于简单的视图可以执行INSERT,UPDATE和DELETE操作,但是对于复杂视图,不允许直接执行INSERT,UPDATE,DELETE操作,当视图出现以下任何一种 ...

  3. 二维码生成 - QrCodeNet

    下载QrCodeNet /// <summary> /// 生成QR码 /// </summary> /// <param name="output_path& ...

  4. hdu5360 Hiking(水题)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Hiking Time Limit: 6000/3000 MS (Java/Oth ...

  5. (原)torch7中添加新的层

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6069627.html 参考网址: http://torch.ch/docs/developer-doc ...

  6. wind7下搭建ftp服务器

    一.首先在本地机器上创建一个用户!这些用户是用来登录到FTP的!我的电脑右键->控制面板->管理工具->计算机管理->本地用户和组->用户->“右键”新建用户-&g ...

  7. python 杂记

    class TestA(object): def __init__(self): print("A is initing"); def foo(self): print(" ...

  8. python学习第三天 --布尔类型

    我们已经了解了Python支持布尔类型的数据,布尔类型只有True和False两种值,但是布尔类型有以下几种运算: 与运算:只有两个布尔值都为 True 时,计算结果才为 True. True and ...

  9. Python函数小结(2)-- 装饰器、 lambda

    本篇依然是一篇学习笔记,文章的结构首先讲装饰器,然后讲lambda表达式.装饰器内容较多,先简要介绍了装饰器语法,之后详细介绍理解和使用不带参数装饰器时应当注意到的一些细节,然后实现了一个简单的缓存装 ...

  10. mysql 高效分页控件及c#调用实例

    第一.首先在mysql中创建一个存储过程 BEGIN /* @selectSql VARCHAR(5000), --sql语句 @orderWhere VARCHAR(200), --排序条件 @pa ...