const 成员函数重载

先看一段引用[1]:

许多人漠视一件事实:两个成员函数如果只是常量性(constess)不同,可以被重载

ok,下面为了解释,定义一下下面这个类:

class Cstring
{
    private:
    char str[32];
    public:
    Cstring(char instr[], size_t n)
    {
        for(int i=0;i<n;++i)
            str[i] = instr[i];
    }
    char& operator [] (size_t i)   
    {
        return str[i];
    }
    const char& operator [] (size_t i) const  //注意这个const 常量,属于函数签名,因此导致重载
    {
        return str[i];
    }
};

然后有以下应用:

    char str[] = "hello world!";
    Cstring cstr(str, sizeof(str)/sizeof(char));
    const Cstring const_cstr(str, sizeof(str)/sizeof(char));


    cout<<cstr[3]<<endl; //非const operator 版本
    cout<<const_cstr[3]<<endl; //const operator版本
    cstr[3] = '1';//ok
    const_cstr[3] = '1';//error ,不能通过编译

然而,如果注释掉const operator 的版本,在GCC编译器中,给以下错误:

error: passing ‘const Cstring’ as ‘this’ argument discards qualifiers [-fpermissive]

所以,基于对class 本身的设计需求,决定要不要写两个版本的operator。

然而对于上述的代码,const 版本与非const版本的代码仅是相差了一个常量性的修饰,为了代码重用,可以做出以下更改:

class Cstring
{
    private:
    char str[32];
    public:
    Cstring(char instr[], size_t n)
    {
        for(int i=0;i<n;++i)
            str[i] = instr[i];
    }
    char& operator [] (size_t i)   
    {
        return const_cast<char&>(
            static_cast<const Cstring&>(*this)[i]
            );
    }
    const char& operator [] (size_t i) const
    {
        return str[i];
    }
};

注意到,这次我们让non-const 调用了const 版本的函数,但是在调用的时候,我们使用了转型的操作。
首先是为对象本身加上const 属性,这个使用static_cast
然后返回值去掉const属性,这个使用const_cast
虽然使用转型会一定程度上损失效率,但是代码重复也是一件恼人的事情。那么在两者之间如何抉择倒是视需求而定了。
在[1]中有句名言:

二八定律:程序80%的时间是由20%的代码贡献的

所以如何去提高程序的运行效率,去思考如何改善那20%的代码更为重要:)

参考资料
[1] Scott Meyers 著, 侯捷译. Effective C++ 中文版: 改善程序技术与设计思维的 55 个有效做法[M]. 电子工业出版社, 2011. (条款03:尽可能使用const)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值