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. (一)Activity参数传递

    1.主Activity,用于启动另一个Activity()public class MainActivity extends Activity { @Override protected void o ...

  2. 委托,匿名方法,Lambda,泛型委托,表达式树

    一.委托:完成一个委托应分三个步骤://step01:首先用delegate定义一个委托;public delegate int CalculatorAdd(int x, int y);//step0 ...

  3. $.fn、$.fn.extend和$.extend的区别

    $.fn $.fn是指jquery的命名空间,加在fn上的方法及属性,会对jquery实例每一个有效. 如:扩展$.fn.abc(),即$.fn.abc()是对jquery扩展了一个abc方法,那么后 ...

  4. hdu 1262寻找素数对

    Problem Description 哥德巴赫猜想大家都知道一点吧.我们现在不是想证明这个结论,而是想在程序语言内部能够表示的数集中,任意取出一个偶数,来寻找两个素数,使得其和等于该偶数. 做好了这 ...

  5. Qt Creator的配置

    说明:一直想入手QT,看了相关的教程也有一段时间了,但苦于安装QT编辑器一直没有成功,今天手痒痒,于是又来捣鼓一阵子,成功了,特记录下来,方便日后查阅: 环境:win7 x64  + QT Creat ...

  6. javaWeb--jsp & jQuery

    jsp页面的基本构成:指令标签HTML标记语言注释   <!-- html注释 -->  <%-- java代码注释 -->   //html注释对jsp嵌入的代码不起作用,因 ...

  7. LeetCode_Populating Next Right Pointers in Each Node II

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  8. 时刻注意QT与Windows系统的不同(惨痛教训)

    其实就一条:WINAPI使用'\',而QT使用'/'.如果程序立刻崩溃的话,是很难看出端倪的,所以要时刻注意...

  9. 【转】 Git 常用命令详解(二)----不错

    原文网址:http://blog.csdn.net/ithomer/article/details/7529022 Git 是一个很强大的分布式版本管理工具,它不但适用于管理大型开源软件的源代码(如: ...

  10. Message Authentication Code