【const】

0.普通const对象定义在栈空间中

{
int a = ;
const int b = ;
cout << &a << ' ' << &b;
} Result:

 0x22abec 0x22abe8

注:Code::Blocks + Cygwin测得。

1.对变量类型加以限定,使之不能被修改;

const int e1 = 100;

e1 = 101; // error

2.const对象必须被初始化;

const int e2; // error

3.const对象和non-const对象可以通过彼此进行赋值;const对象也可以通过表达式进行初始化;

int get_size() { return ; }

int main()
{
int i = ;
const int a = i; // non-const to const
const int b = a; // const to const
int c = a; // const to non-const
int d = i; // non-const to non-const int e = get_size(); return ;
}

4.默认情况下,const对象仅在文件内有效(From定义之后To文件末尾);

5.要在多个文件内共享一个const对象,需要使用extern关键字;

《C++ Primer》第五版的说法有一点问题,即“对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次就可以了”。

经过测试:可以在定义时不添加extern关键字,即下面的代码是可行的:

// file1.cpp
const int a = ; // file2.cpp
extern const int a;

但在声明和定义时都添加extern关键字应该是“最佳实践”,即在定义时就说明此const变量为整个工程可见。

6.const引用

6.1 不能通过const引用修改对象的值,无论其指向的对象是否为const对象;

6.2 非const引用不能指向一个const对象;

{
int i = ;
const int a = i; int& b = i;
int& c = a; // error, 6.2
const int& d = i;
d = ; // error, 6.1
const int& e = a;
e = ; // error, 6.1
}

6.3 将一个const引用绑定到另外一种类型上发生了什么:

{
double dval = 3.14; const double& rd = dval;
const int& ri = dval; cout << &dval << ' ' << &rd << endl;
cout << &dval << ' ' << &ri << endl;
} Result:
0x22abd8 0x22abd8 // ok
0x22abd8 0x22abe4 // wrong!

整形const引用的地址和dval的地址不一致。《C++ Primer》解释说,这是因为类型转换发生时,ri指向的是一个临时变量,并且,C++将这种行为归为非法。

但却能run起来。

7.指向和const

7.1 指向const对象的指针(pointer to const):a.禁止指向非const对象的指针 指向 const对象;b.禁止将 指向const的指针 赋值给 指向非const的指针;

7.2 不能更改指向const对象的指针的值;

{
const double cpi = 3.14;
double *ppi = &cpi; // error, 7.1.a
const double *cppi = &cpi; double pi = 3.14;
double *ppi2 = &pi;
*ppi2 = 1000.0;
const double *cppi2 = &pi;
ppi2 = cppi2; // error, 7.1.b
*cppi2 = 100.0; // error, 7.2
}

7.3 常量指针(const pointer):必须初始化、一旦完成初始化就不能更改、若所指对象非const,则可以修改其值;

{
int a = ;
int b = ; int *p1 = &a;
*p1 = ;
p1 = &b; int* const cp2 = &b;
*cp2 = ; // ok
cp2 = &b; // error, pointer is const int* const cp3; // error, uninitialized
}

8.顶层const,底层const

顶层const:对象本身是否为常量,整数本身、对象本身、指针本身,即自己,不能改变自己;

底层const:指针 所指对象是否为常量,不能改变指针 所指对象 的值;

const int * const pi = &a; // 1.前一个const为底层const,后一个const为顶层const;2.从右往左阅读法;

9.类与const

9.1 const成员函数

作用:修改隐式this指针的类型。添加const之后,this指针所指对象的普通数据成员(非static非mutable)不能被更改。

类型转换实值:将 T* const this 更改为 const T* const this,此时,this指针所指对象可以是const对象。

9.2 const对象,以及const对象的引用或指针都只能调用const成员函数;

struct X {
X(int x, int y) : ex(x), ey(y) {}; void display1() { cout << ex << endl; }
void display2() const { cout << ey << endl; } int ex;
int ey;
}; int main()
{
X x(, );
x.display1();
x.display2(); const X cx(, );
cx.display1(); // error, display1为非const成员函数
cx.display2(); return ;
}

9.3 若成员函数为const,则其声明和定义都必须添加const(与上面说的extern的用法不同);

9.4 成员函数可以根据const属性进行重载;

struct X {
void display() {}
void display() const {}
};

9.5 const成员变量:a.不能被修改;b.能进行类内初始化;c.若已类内初始化,则可以使用默认构造函数;d.可以在构造函数初始化列表中初始化;

 struct X {
X() {}; // 默认构造函数
X(int x, int y) : ex(x), ey(y) {}; void display1() { cout << ex << endl; }
void display2() const; const int ex = ; // 类内初始化
const int ey = ; // 类内初始化
};
void X::display2() const { cout << ey << endl; }

若未进行类内初始化,则默认构造函数不能通过编译,即当上面代码的8、9行没有赋值时,上面的默认构造函数不能通过编译,无论是否用到此默认构造函数;

若未进行类内初始化,又需要使用默认构造函数,可以在默认构造函数的初始化列表中给const成员变量赋值:

X() : ex(), ey() {};

其中的99、100可以更改为其它表达式:

int out1 = ;

struct X {
X() : ex(out1), ey(out1+) {}
...
};

-------------------------------------------------------------------

其它:

1.用于声明引用的const都是底层const,即不存在顶层const

const int a = 100;
const int & const b = a; // error: 'const' qualifiers cannot be applied to 'const int&'

2.引用可以赋值给引用

int a = 10;

int& b = a;

int& c = b; // ok, b is a reference

但const引用不能赋值给非const引用

const int& c = a;

int& d = c; // error

C++中const的更多相关文章

  1. C、C++中const的区别

    C语言中: 被const修饰的变量,仍然是变量.虽然不能用C语法给这个变量改变值,但他本质上还是变量. C编译器会给它分配空间. C中,const默认使用的是外部链接. C++中: 被const修饰的 ...

  2. JavaScript中const、var和let区别浅析

    在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始 ...

  3. C/C++中const的用法 分类: C/C++ 2015-07-05 00:43 85人阅读 评论(0) 收藏

    const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂.const用于定义一个常变量(只读变量),当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多.下面将从五个方面总结 ...

  4. C++中const 的各种用法

    C++中const 关键字的用法 const修饰变量 const 主要用于把一个对象转换成一个常量,例如: ; size = ; // error: assignment of read-only v ...

  5. (转) C/C++中const关键字详解

    文章转自  http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html 为什么使用const?采用符号常量写出的代码更容易维 ...

  6. 实例讲述PHP面向对象的特性;;;php中const与define的使用区别

    php中const与define的使用区别 1.const:类成员变量定义,一旦定义且不能改变其值. define:定义全局常量,在任何地方都可以访问.2.define:不能在类中定义,而const可 ...

  7. C++中const简介及用法

    1.const简介 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰 ...

  8. C/C++ 中 const 修饰符用法总结

    C/C++ 中 const 修饰符用法总结 在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家 ...

  9. C++中const用法详解

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

  10. C++ 中 const和define的区别

    来源网址:http://wujiangping.blog.163.com/blog/static/195182011201255115125205/ 请区别用#define命令定义的符号常量和用con ...

随机推荐

  1. 数据链路层-点对点协议PPP

    在通信质量较差的年代,在数据链路层使用可靠传输协议曾是一个好的办法.因此,能实现可靠传输的高级数据链路控制HDLC(High-Level Data Link Control)就称为当时比较流行的数据链 ...

  2. 01--从根源种子CCNode说起

    CCNode作为渲染框架的基类(暂且这样理解,CCObject为引擎基类)其中定义了绘制游戏元素相关的属性以及相关方法.属性当中需要注意的一个是Z坐标,在渲染框架中用来表示元素的遮挡关系,其值越小越容 ...

  3. Dede修改文章默认标题长度,让标题全显示

    第一步首先你要进入dedecms后台,系统——系统基本参数——其他选项——文档标题最大长度——在这修改为200或更大(其实200应该是足够了). 第二步进入phpmyadmin,点击dede_arch ...

  4. mac qq截图功能失效后,如何重启截图功能?

    在finder中打开应用程序目录,找到QQ,右键单击QQ,选择显示包内容,此时会打开一个文件夹. 进入以下路径Library/LoginItems然后双击ScreenCapture这个进程,截图功能即 ...

  5. 前端jquery实现点击图片弹出大图层(且滚动鼠标滑轮图片缩放)

    <img src="{$vo.photo}" height="50px" onclick="showdiv({$i});"> & ...

  6. MVC入门之.Net语法学习

    本节中主要学习.Net框架性语法.开发者可以使用新语法提高编程的效率以及代码的运行效率:其本质都是“语法糖”,由编译器在编译时转成原始语法. u  自动属性 Auto-Implemented Prop ...

  7. Winform(C#)限制程序只运行一个实例

    C#控制只运行开启一个程序 在这个例子中不需要调用ReleaseMutex,mutex会在程序结束时自动释放.为了防止mutex过早释放,在程序的最后调用下GC.KeepAlive (mutex). ...

  8. PHP-FPM小故障解决记录

    前天昨天发生的事. 阿里云升级MYSQL,申请只读库之后,IP发生了改变,PHP中关于数据库的连接都需要修改. 我们是以实例名作为统一连接字符的. 但在其中一台后端机器上,死活不生效. 就是如何是用I ...

  9. hex、bin、elf、axf文件区别

    AXF和ELF axf文件是ARM的调试文件,除了包含bin的内容之外,还附加了其他的调试信息,这些调试信息加在可执行的二进制数据的前面.在调试的时候,这些调试信息是不必下到RAM中去的,真正下到RA ...

  10. wikioi1191 数轴染色

    题目描述 Description 在一条数轴上有N个点,分别是1-N.一开始所有的点都被染成黑色.接着 我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色.请输出每个操作执行后 剩余黑色点的个 ...