现在的位置: 首页 > 综合 > 正文

C++编程思想读书笔记-8常量

2013年09月14日 ⁄ 综合 ⁄ 共 2028字 ⁄ 字号 评论关闭

1 头文件里的const

const默认为内部连接(internal linkage),仅在本文件内可见.

为了使const能够被外部文件所引用,必须明确把它定义成extern

extern const int x = 1; 

这样是是对常量做定义,而不是声明.

声明是这样的 extern const int i; 表示在其它地方有定义一个常量i;

2 const的空间分配问题

1 通常c++编译器并不为const创建存储空间,将它的定义保存在符号表里,这个叫编译期间的常量(可以用来给数组定义大小)

2 当extern是定义的一部分时,(同1中一样, 是定义不是声明),意味着不同的编辑单元可以引用它,所以它必须有存储空间

3 当下文中有取常量的地址时,常量也要分配存储空间.但这不妨碍编译器知道它是常量,仍然可以用来定义数组的大小.

4 当const用于定义数组或者自定义类型时(书中用的是"聚合"aggregate这个词),编译器不会将一个聚合保存在符号表中,因此要分配存储空间,并且它不是一个编译期间的常量.

例如

const int i[] ={1,2,3,4};
float f[i[3]]; //Illegal

5 const在C语言中的意思是"一个不可改变的变量".在C语言中,const总是占有存储并且全局连接,因此不可以当作一个编译期间的常量,

例如 :在c语言中,如下代码是非法的

const int bufsize=100;
int buf[bufsize];

6 总结: C++是否为常量分配存储空间取决于如何使用.

 如果仅仅只把一个名字用一个值代替(累似#define),就不分配存储空间,

如果取常量地址 常量是聚合类型 将常量定义成extern ,就需要分配存储空间.

只要不是聚合类型,就可以当作编译期间常量使用

3 const指针

指向const的指针 const int *a; int const *b;  (const在*左边)

const指针 
int *const c; (const在*右边)

指向const的const指针 const int * const a; 或者 int const * const a;

4 赋值和类型检查

不能将一个const对象的地址赋给非const指针

这个检查主要在赋值和函数参数为指针时 进行检查

这个规则有个例外:

char *cp = "howdy";

5  参数传递和返回值

1 传递const 值

函数内参数不可变

2 返回const值

返回值是内建类型时,const是无关紧要的,因为它总是一个值而不是一个变量, 建议去掉const

返回值是自定义类型时,表示返回值不可以做左值(不能被赋值,也不能被修改)

3  传递const指针

无论什么时候传递一个地址给一个函数,都应该尽可能地用const修饰它,如果不这样做,就不能以const指针参数的方式使用这个函数

4 返回const 指针

返回值是const int *(指向const的指针)  只能被const int *指针接收

返回值是const int * const(指向const的const指针)  能被const int * const 和const int *接收,都表示指向的目标不被改变

但不能做为左值

5 C++中出现的新情况: 临时变量的地址传给函数
一个总是const的临时变量,它的地址可以被传递给函数.(使用引用,不能使用指针)
记住 临时变量总是const
class X{};
X f(){return X();}
void g1(X &){}
void g2(const X&){}

int main()
{
g1(f()); //错误
g2(f()); //正确
}

为什么C语言中做不到呢? 因为参数是指针时,必须明确指明地址

6 类中的const变量
1 普通const成员变量总会被分配存储空间,并且不会在类声明中赋初值 ,初值必须在构造函数的初始化列表中赋值.
所以普通const成员函数不能做为编译时常量使用
2 static const成员变量 可以看作编译期间的常量,因为static标记的变量只初始化一次, static const变量在类定义中初始化

(回忆: 普通static变量是在类中声明,类外定义的)

3 enum hack

不带实例的enum 

一个枚举在编译期间必须有值, 并且不会占用类的存储空间

class Bunch

{

enum{ size = 1000};

int buf[size];

};

4 const成员函数

1 const放在函数后面,代表该函数不会改变成员变量 

2 声明函数和定义函数 都要加const 否则认为是两个不同函数

3 const对象只能调用const成员函数, const对象调用两个同名函数时 调用的是const函数

4 在const成员函数中要如何改变成员变量?

在成员变量前面加 mutable 代表该变量可以在const成员函数中进行修改

5 const violate

violate代表"在编译器认识的范围外,该值可能改变" ,因此编译器不能对该值做任何假定,每次都必须去该值所在的地址读取

const violate变量表示 程序员不可以修改,但外部的代理程序可能修改的变量.

【上篇】
【下篇】

抱歉!评论已关闭.