《Effective c++》 条款3:尽可能的使用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

常量指针和指正常量有区别?我的之前的博客里面提到过:https://blog.csdn.net/m0_37690319/article/details/79607836,如果有兴趣可以看一看,很多人说了方法const在*左边表示被指物是常量,如果在const在*右边表示指针是常量,指针的指向是不能改的,举个例子:const char *p=greeting ,别指物是常量,有人会问那就是greeting是常量,那为什么我直接greeting[0]='w';没有出错

char greeting []="hello";   
char *p=greeting; 
p[0]='w';        //error
greeting[0]='w'; //正确

关于const的下面两种方式都是可以的,是一个意思,但是要注意啊,const *char,我本人也从来没见过,同时也是一种错误的写法,但是char * const 是有的。参考上面

const char *p=greeting;
char const *p=greeting;

 补充一个迭代器的知识点,迭代器是按照指针的模型建造出来的,我们如果要一个迭代器的指向不能改,但是指向的东西是能改的,或者迭代器指向的东西不能更改,

std::vector<int> vec;
const std::vector<int> ::iterator iter=vec.begin();
std::vector<int> :: const_iterator citer=vec.begin();

const 成员函数

       const成员你函数就是不允许修改改成员变量的值,const对象只能调用const成员函数,所以可以看看下面的类。

class TextBlock
{
public:
    const char & operator[](std::size_t position) const  //前面的额const char & 表示返回一个常量的引用,后面的const表示是const成员函数
    { return text[position]; }
    char & operator [](std::size_t position)
    { return text[position];}
pricate
    std::string text;
};

//调用情况,类中的构造函数省略,
TextBlock tb("hello");    
std::cout<<tb[0];                    //调用非const
const TextBlock ctb("world");
std::cout<<ctb[0];                    //const对象只能调用const成员函数


tb[0]='x';                            //注意这里是对返回的引用改变
ctb[x]='x';                           //错误,不能对const 对象改变

注意一个问题:函数的返回值是内置类型,那么改动函数的返回值是不合法的,因为他返回的是右值,char & 如果换成 char,那么tb[0]='x'; 在这句话相当于在对char operator [](std::size_t position)这个函数的返回值进行赋值。

现在问一个问题,const成员函数就一定不更改对象的内容吗?看看下面的例子

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

pricate
    char * ptext;
};

const CTextBlock cctb("hello");
char *pc=&cctb[0];
*pc='j';

最终打印出来的是”jello“,有点超乎我们的想象,所以有时候const成员函数可以间接的修改内部对象的某些bit ,当然还可以使用另外的一种方法来修改,将成员对象声明为 mutable。

再问一个问题?为什么类的设计里面  同一个操作符要设置const版本和非const版本?因为const对象只能调用const成员函数,那我们可能会碰到这样的情况,

class TextBlock
{
public:
    cosnt char & operator [](std::size_t position) const 
    {
        ...//边界校验
        ...//日志访问
        ...//检验数据的完整性
        return text[position];    
    } 

    char & operator[] (std::size_t position)
    {
        ...//边界校验
        ...//日志访问
        ...//检验数据的完整性
        return text[position];
    }

private:
    std::string text;

};

甚至有人会问,何有什么问题吗?。。。。的确没什么问题,但是代码有些冗余,你也可以回答不就赋值粘贴一下吗,不麻烦。。。。。代码的重复面临着编译的时间,代码维护、代码膨胀,那么看看下面的方法

class TextBlock
{
public:
    cosnt char & operator [](std::size_t position) const 
    {
        ...//边界校验
        ...//日志访问
        ...//检验数据的完整性
        return text[position];    
    } 

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

private:
    std::string text;

};

将*this转换为 const去调用operator[]的const版本,const版本的返回值是 const char &,然后调用const _cast去掉const属性,这样就减少了代码的冗余,但是不要尝试这个方法的反响做法,在const版本里面去调用非const版本,这会产生不安全

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值