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. vb将窗体中的控件或某种颜色透明

    Option Explicit ' ******************** 窗体透明 ******************** '***Module.bas '**** Public Declare ...

  2. Lanucherr 默认显示第几屏

    Launcher.java static final int SCREEN_COUNT = 5;static final int DEFAULT_SCREEN = 2;//第一页是从0开始计数,这里是 ...

  3. 正则表达式,Regex类

    C#regex是正则表达式类用于string的处理,查找匹配的字符串.1,先看一个例子Regex regex=new Regex(@”OK“)://我们要在目标字符串中找到"OK" ...

  4. C#总结(一)

    学C#也有两年多了,发现如果不总结一下,很多C#的知识都会忘掉,所以希望写这系列的文章来总结一下C#的基础知识.如果有写错或者不足的地方,希望可以提出纠正. C#可以说是依附在.NET Framewo ...

  5. 脚本化HTTP

    1.HTTP: 定义:超文本传输协议 (HTTP-Hypertext transfer protocol) 是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协 ...

  6. C#将十六进制的文本转换到整型数据

    1 length1 = Int32.Parse(szLine.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);//计算这一行 ...

  7. Sql server统计查询语句消耗时间

    1. set statistics time on go  xxxx go set statistics time off 2. DECLARE @begin dateTime DECLARE @en ...

  8. python - num1 -初识python

    一.了解python python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...

  9. Double Strings Solved Problem code: DOUBLE

    # Fuking silly, OTZ.... import sys def main(): n = int(raw_input()) for num in sys.stdin: if int(num ...

  10. [1] Tornado Todo Day0

    Github地址: day0 初始化数据库: jakeychen@JC:~/Public/tornado_todo$ pwd /home/jakeychen/Public/tornado_todo j ...