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

条款3 尽可能使用const

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

char greeting[] = "Hello";
char *p = greeting;            //non-const pointer,non-const data
const char*p = greeting;       //non-const pointer,const data
char *const p = greeting;      //const pointer,non-const data
const char *const p = greeting;//const pointer,const data

2. STL迭代器系以指针为根据塑模,类似T* ,被const 修饰的迭代器不能指向其他内存对象,但是所指物的值是可改变的,若需要所指物不可改动,则申明类型为const_iterator:

std::vector<int>vec;
...
const std::vector<int>::iterator iter = vec.begin();//iter的作用像个T* const
*iter = 10;                                         //OK,可改变iter所指物
++iter;                                             //No!iter是const
std::vector<int>::const_iterator cIter = vec.begin();
*cIter = 10;                                        //No!*cIter是const
++cIter;                                            //OK,改变cIter

3. const与函数返回值,参数,函数自身(如果是成员函数)产生关联,借助编译器侦测出错误用法

    令函数返回一个常量值,不能改变使用参数的引用:

class Rational{...};
const Rational operator*(const Rational &lhs,const Rational &rhs);

    这只是单纯的重载*号运算符,当函数返回类型为non-const的话:

Rational a,b,c;
...
(a*b) = c;
if(a*b = c)...

在a*b的成功上调用operator=,成功的对乘积做了一次赋值(assignment),可能也只是打字错误

4. const成员函数,将const实施于成员函数的目的,为了确认该成员函数可作用于const对象身上。如果成员函数只是常量性不同,可以被重载,这类成员函数的重要理由:

 a.使class接口容易理解,哪些函数可以或不可以改动对象内容

 b.这使改动const对象成为可能

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

    可以这样使用:

TextBlock tb("Hello");           
std::cout<<tb[0];               //正确-读non-const     
tb[0] = 'x';                    //正确-写non-const
const TextBlock ctb("World");    
std::cout<<ctb[0];              //正确-读const
ctb[0] = 'x';                    //错误!写const
5.  编译器强制实行 bitwise constness(又称 physical constness,物理上的常量性,即成员函数不更改对象的任何一个bit时才可以说是const),例如:
class TextBlock{
public:
    ...
    char& operator [](std::size_t position) const{
        return pText[position];
    }
private:
    char* pText;
}

扫描二维码关注公众号,回复: 1939619 查看本文章

    编译器认定它是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实现重载.

6. 当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特性相矛盾.

7.对于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;
}






猜你喜欢

转载自blog.csdn.net/yuleidnf/article/details/80951999
今日推荐