Effective C++ 条款3 尽可能用const

1. const可被施加于任何作用域内的对象,函数参数,函数返回类型,成员函数本体.用const修饰指针,如果const出现在*之前,表明指针不能更改所指向的对象的内容,如果const出现在*之后,表明指针只能指向同一块内存.另外int const*p和const int*p含义相同.如果对象成员有普通指针,那么构造该类的一个const对象时,const修饰使得该指针只能指向同一块内存,但指针指向的内容可以改变.

2. 将某些东西声明为const可以帮助编译器侦测出错误用法.

3. 编译器强制实行bitwise constness(又称physical constness,物理上的常量性,即成员函数不更改对象的任何一个bit时才可以说是const),例如:

class TextBlock{
public:
    ...
    char& operator [](std::size_t position) const{
        return pText[position];
    }
private:
    char* pText;
}

编译器认定它是bitwise constness的,但是它却允许以下代码的存在:

const CTxetBlock cctb("Hello");
char* pc=&cctb[0];
*pc=‘J‘;

这是由于只有pText是cctb的一部分,其指向的内存并不属于cctb

程序员编写程序时应该使用conceptual constness(概念上的常量性或logical constness,逻辑上的常量性,即一个const成员函数可以处理它所修改的对象的某些bits,但只有在客户端侦测不出的情况下才得如此),例如对于某些特殊类,其中的某些成员的值注定是要改变的,因此可以用mutual关键字修饰,从而实现即使对象被设定为const,其特定成员的值仍然可以改变的效果.此时该类符合conceptual constness而不符合bitwise constness.

4. 如果参数是引用,可以基于参数是否为const实现函数重载(也可以基于指针是否为const实现函数重载),特殊的,对于成员函数,因为它存在一个隐含的this指针参数,因而可以基于函数是否为const实现重载.

5. 当const和non-const成员函数拥有重复的实现时,令non-const版本调用const版本可避免代码重复,例如对于以下实现:

class TextBlock{
public:
    ...
    const char& operator[](std::position) const{
        ...
        return text[position];
    }
    char& operator[](std::position) {
        ...
        return text[position];
    }
private:
    std::string text;
}

通过令non-const版本调用const版本如下:

class TextBlock{
public:
    ...
    const char& operator[](std::size_t position) const{
        ...
        return text[position];
    }
    char operator[](std::size_t position){
        return const_cast<char&>(
             static_cast<const TextBlock&>(*this)[position]);
    }
    ...
};

可以看出,经过了两次类型转换,第一次通过static_cast将*this转为const TextBlock&以确保调用的是operator[]的const版本,否则会调用非const版本导致递归调用造成栈溢出;第二次通过const_cast去掉const版本的opsrator[]返回的const char&的const特性以与函数的返回类型相匹配.

注意,不能用const版本调用non-const版本,因为non-const版本极有可能改变对象的值,这与const版本的const特性相矛盾.

6.注:对于const_cast的行为之前存在一些误解,对于以下代码:

#include<iostream>
using std::cout;
using std::endl;
int main(){
    const int a = 5;
    int& rta = const_cast < int&>(a) ;
    rta = 6;
    cout << "a: " << a << "    rtr: " << rta << endl;
    cout << "&a: " << &a << "     &rta: " << &rta;
    system("pause");
    return 0;
}

输出结果如下:

可见虽然const_cast表面上改变了变量的const性质,但a的值实际上还是没有改变(编译器仍然背着我们干了不少事),所以const_cast的实际用途并不是改变const对象的值,而是"暂时"去除对象的const属性使其可以作为参数传入非const函数,企图通过const_cast改变const对象的值可能会导致未预料的结果.因此个人认为5中的第二段代码(出自Effective C++ “条款3  尽可能用const”)存在一些错误,如有错误欢迎批评指正!

时间: 2024-11-17 01:41:57

Effective C++ 条款3 尽可能用const的相关文章

Effective C++ 条款三 尽可能使用const

参考资料:http://blog.csdn.net/bizhu12/article/details/6672723      const的常用用法小结 1.用于定义常量变量,这样这个变量在后面就不可以再被修改     const int val = 90;      val = 100;   错误 2. 保护传参时参数不被修改,如果使用引用传递参数或按地址传递参数给一个函数,在这个函数里这个参数的值若被修改, 则函数外部传进来的变量的值也发生改变,若想保护传进来的变量不被修改,可以使用const

Effective C++ -----条款03:尽可能使用const

如果关键字const出现在星号左边,表示被指物是常量:如果出现在星号右边,表示指针自身是常量:如果出现在星号两边,表示被指物和指针两者都是常量. char greeting[] = " hello"; char* p = greeting;  //non-const pointer,non-const data const char* p = greeting;  //non-const pointer,const data  声明p为一个指向常量的greeting的指针,p指向的对象

Effective C++ Item 3 尽可能使用const

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie const 出现在*左边指const data,出现在*右边指const pointer char greeting[] = "Hello"; char *p = greeting; //non-const pointer, non-const data const char *p = greeting; //non-const pointer, const data char

条款21: 尽可能使用const

对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const,还有,两者都不指定为const: char *p = "hello"; // 非const指针, // 非const数据 const char *p = "hello"; // 非const指针, // const数据 char * const p = "hello"; // const指针, // 非const数据 const char

Effective C++ 条款2 尽量以const,enum,inline替换#define

1. 有些情况下,宁可以编译器替换预处理器,因为#define并不被视为语言的一部分从而导致某些问题. 2. 不带参数的宏展开引起的符号"丢失"问题. 例如,对于"#define ASPECT_RATIO 1.635",编译器在处理源代码之前ASPECT_RATIO就已经被替换为1.635,于是记号名称有可能没有进入记号表(symbol table)内.如果由于运用此常量而获得一个编译错误,错误信息可能会提到1.635而不是ASPECT_RATIO,追踪它将会浪费时

effective c++ 条款3 use const whereever you can

1 const 传达的意思应该是这个变量是常量不能更改 2 const 在 * 左边表示数据是const,在右边表示指针是const // char greeting[] = "hello"; char* p = greeting; //const *: const data //* const: const pointer char const *p1 = greeting; // const data char * const p2 = greeting; // const poi

Effective C++ 之 Item 3:尽可能使用 const

Effective C++ Chapter 1. 让自己习惯C++(Accustoming Yourself to C++) Item 3. 尽可能使用 const (Use const whenever possible) 1. const 与语义约束 const 允许指定一个语义约束(也就是指定一个"不该被改动"的对象),而编译器强制实施这项约束.它可以在 classes 外部修饰 global 或 namespace(见 Item2)作用域中的常量,或修饰文件.函数.或区块作用域

Effective C++ Item 26 尽可能延后变量定义式的出现时间

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率. 示例: //这个函数过早定义变量"encrypted" std::string encryptPassword(const std::string &password){ using namespace std; string encrypted; if(password.length() <

More Effective C++ 条款35 让自己习惯于标准C++ 语言

(由于本书出版于1996年,因此当时的新特性现在来说可能已经习以为常,但现在重新了解反而会起到了解C++变迁的作用) 1. 1990年后C++的重要改变 1). 增加了新的语言特性:RTTI,namespaces,bool,关键词mutable和explicit,enums作为重载函数之自变量所引发的类型晋升转换,以及"在class 定义区内直接为整数型(intergral) const static class members设定初值"的能力. 2). 扩充了Templates的特性