您的位置:首页 > Web前端

Effective 3.尽可能的使用const

2017-06-04 10:07 141 查看
尽量一天一个条款的节奏吧。今天写关于const的,const在c++中很平常,可是知道什么时候应该运用,什么时候用他来取代什么,却是一个没想过的问题,这个条款中详细的介绍了关于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


总结下: const 出现在星号左边,表示被指物是常量,出现在星号右边,表示指针自身是常量。(感觉这个自己看看就好,不用记啊!!!)

在const修饰的常量,只跟星号左右有关系,跟类型没有关系。

对于 STL中 , C++也是有const指针的,也就是const_iterator. 但是跟上述的优点不一样。

看下如下代码。

std::vector<int> vec;
const std::vertor<int>::iterator iter = vec.begin();
*iter = 10;     // 没问题 改变了iter的data.
++iter;         // 错误,iter是一个const.
std::vertor<int>::const_iterator Citer = vec.begin();
*cIter = 10;    //错误,*cIter是个const
++cIter;        //没问题改变了cIter


所以看起来stl中的修饰,跟平常的不一样,有点相反的样子。

重点来了!!const 最有威力的地方,是在函数声明的时候进行运用。

1. 让函数返回一个常量值,可以降低别人调用的时候发生意外的情况。(请不要假设调用你写的函数的人都能去看你的函数。或者知道这个函数的正确的用法, 有些时候,他的用法让你完全想不到 !!!!)

class Rational(....);
const Rational operator*(const Rational& lhs, const Rational&rhs); //下面解释为什么返回值用const修饰。
Rational a,b,c;
(a*b) = c;  //如果返回值不是const 是不是就成功了! 别问为什么有人会这么用!!有可能!!
if(a*b = c) //判断语句少打一个等号!是不是有可能发生!是不是可以减少好多错误的可能性!总比调试好


2 const 成员函数。

目的: 是为了确认该成员函数可作用于const对象身上。

理由: 1 。 接口便于理解,哪个函数可以改动对象内容,哪个不行(const成员函数不会改动对象内容 理论上。。。)。2,它们使“操作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 Operator[]
tb[0] = 'x';                //成功,返回的不是const对象

TextBlock ctb("Hello");
std::cout << ctb[0];        //调用 const Operator[]
ctb[0] = 'x';               //错误,返回的是const对象


对于tb[0] = ‘x’ ,如果返回值是char 不是指针,那么这个改动是不合法的,如果合法,改动的 也是他的副本,不是改动对象的本身,所以要注意这点。

如果const 函数返回一个指向成员内部的指针,就打破了对const的函数的理解的和运用(有点小疑问,回头验证下。)

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

const CTextBlock cctb("Hello");
char * pc = &cctb[0];
*pc = 'J';      //修改了hello 违背了初衷。


“`

如果想在const函数中改变 成员变量, 可以用 mutable来声明。

如果为了避免代码的重复, 也就是让const的常量性消失, 可以领non-const函数调用const函数。中间可能需要一个转型工作。(const_cast 消除const static_cast (增加const性) 后面条款会详细说明转型操作)

const 成员函数是不允许调用non-const成员函数的,违背了const 函数的初衷,不改变对象的内部数据在const函数中。尽量使用const可以提高代码的效率和安全性。

请记住

将某些声明声明为const 可以帮助编辑器侦测出错误用法。const可以被施加于任何域内对象,函数参数,函数返回值,成员函数本体。

对const函数,我们应该编写概念上的常量性。

当const 和non-const 成员函数的代码重复的时候,我们应该用non-const函数成员调用const函数,避免代码重复。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  effective-c++