Chinaunix首页 | 论坛 | 博客
  • 博客访问: 547489
  • 博文数量: 80
  • 博客积分: 3172
  • 博客等级: 中校
  • 技术积分: 773
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-15 11:35
文章存档

2012年(5)

2011年(12)

2010年(11)

2009年(52)

我的朋友

分类: C/C++

2009-04-21 17:30:27

《C/C++高质量程序设计》笔记之常量

 


    有时我们希望某些只在类中有效。由于 #define 定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用 const 修饰成员来实现。 const 数据成员的确是存在的,但其含义却不是我们所期望的。非静态 const 数据成员是属于每一个对象的成员,只在某个对象的生存期限内是常量,而对于整个类来说它是可变的,除非是 static const 。因为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同。

    不能在类声明中初始化非静态 const 数据成员。因为在类的对象被创建之前,编译器无法知道该常量的值。
class A
{
    ...
    const int SIZE = 100;    // 错误
    int array[SIZE];    // 错误,未知的 SIZE
};
非静态 const 数据成员的初始化只能在类的构造函数的初始化列表中进行。

    那么,怎样才能建立在整个类中都恒定的常量呢?应该用类中的枚举常量来实现,不过只能用于整数。
class A
{
    ...
    enum
    {
        SIZE1 = 100,
        SIZE2 = 200
    };
    int array1[SIZE1];
    int array2[SIZE2];
};

枚举常量不会占用对象的存储,它们在编译时被全部求值。

    还可以使用 static const 来定义类的所有对象共享的常量。在定义时初始化。
static const int SIZE1 = 100;


    在 C 语言中,用 const 定义的常量其实是值不能修改的变量,因此会给它分配空间。但是在 C++ 中,要看具体情况,对于基本数据类型的常量,编译器会把它放到符号表而不分配存储空间,而 ADT/UDT 的 const 对象则需要分配存储空间。还有一些情况也需要分配存储空间,例如强制声明为 extern 的符合常量或取符号常量的等操作,都将强迫编译器为这些常量分配存储空间,编译器会重新在内存中创建一个它的拷贝,通过地址访问到的就是这个拷贝而非原始的符号常量。对于构造类型的 const 常量,实际上它是编译时不允许修改的变量,如果能绕过编译器的静态类型安全检查,就可以在运行时修改其内存单元。
const long lng = 10;
long *pl = (long *)(&lng);
*pl = 1000;
cout << *pl << endl; // 1000, 修改的是拷贝
cout << lng << endl; // 10,原始常量没变,(注:本人认为是编译器的实现是直接用10替换了 lng)

class Integer {
public:
    Integer() : m_lng(100) {}
    long m_lng;
};
const Integer int_l;
Integer *pInt = (Integer *) (&int_l);
pInt->m_lng = 1000;
cout << pInt->m_lng << endl; // 1000
cout << int_l.m_lng << endl; // 1000

    const 符号只是编译时强类型安全检查机制的一种手段,以帮助程序员发现无意中修改它们的代码并进行纠正,而在运行时无法阻止恶意的修改。
阅读(899) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~