码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-08-18 01:03:50      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:

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;
}
View Code

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

技术分享
const CTxetBlock cctb("Hello");
char* pc=&cctb[0];
*pc=J;
View Code

    这是由于只有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;
}
View Code

    通过令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]);
    }
    ...
};
View Code

    可以看出,经过了两次类型转换,第一次通过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;
}
View Code

    输出结果如下:

技术分享

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

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

标签:

原文地址:http://www.cnblogs.com/reasno/p/4737709.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!