c++有时候需要为类的某个成员函数重载常量与非常量的版本,定义常量版本是为了保证该函数可作用于常量类对象上,并防止函数改动对象内容。但有时两个版本的函数仅仅是在返回的类型不同,而在返回前做了大量相同的工作,那么代码会有大量重复,由此也会带来编译时间和代码膨胀等开销。例如下面的类成员函数:

 #include <string>

 class Test
{
using size_type = std::string::size_type;
public:
const char & operator[](size_type index) const;
char & operator[](size_type index);
private:
std::string str;
}; const char & Test::operator[](size_type index) const
{
//...
//...
//要执行的操作
return str[index];
} char & Test::operator[](size_type index)
{
//...
//...
//要执行的操作
return str[index];
}

  虽然完全可以将执行的相同的动作写在一个新的成员函数里并将其定义为私有的,但这样仍然有函数调用和返回值的重复。一种可行的方法是让两个函数的其中一个调用另一个,如下所示:

 class Test
{
using size_type = std::string::size_type;
public:
const char & operator[](size_type index) const;
char & operator[](size_type index);
private:
std::string str;
}; const char & Test::operator[](size_type index) const
{
//...
//...
//要执行的操作
return str[index];
} char & Test::operator[](size_type index)
{
return const_cast<char &>(static_cast<const Test &>(*this)[index]);
}

  非常量版本调用了常量版本,在这过程中进行了两次转型:

    ①static_cast<const Test &>(*this),将非常量类型的Test对象转换成常量类型(const)的Test对象,即把<Test &>类型的*this转换成<const Test &>类型,再调用常量版本的下标运算符。若没有进行转换直接调用下标运算符,等于函数递归调用自己,将会进入死循环。

    ②const_cast<char &>(),上一步的static_cast<const Test &>(*this)[index]调用了常量版本的下标运算符,返回的类型为const char &,接下来便利用const_cast去除返回值的const属性。

  附注1:

  应该注意函数调用的主宾关系:非常量版本调用常量版本并进行类型转换。反过来的做法则是一种错误的行为,常量版本成员函数不会改变对象的逻辑状态,而在常量版本中调用非常量版本则存在着可能改变对象的风险。实际上这样的代码若要通过编译,需要用const_cast去除*this的const属性,这显然是一种不安全的行为。相反,非常量版本成员函数本来就可以改动对象,因为在函数内部调用常量版本并不会有风险。

  

c++类成员函数重载常量与非常量版本时避免代码重复的一种方法的更多相关文章

  1. 直接调用类成员函数地址(用汇编取类成员函数的地址,各VS版本还有所不同)

    在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一个地址,在需要的时候可以任意转换并直接调用.但对成员函数来说,常规类型转换是通不过编译的,调用的时候也必须采用特殊的语法. ...

  2. C++之static类成员,static类成员函数

    0.static修饰类中成员,表示类的共享数据 1.static类成员 在C++primer里面说过,static类成员不像普通的类数据成员,static类数据成员独立于一切类对象处在.static类 ...

  3. 并发编程: c++11 thread(Func, Args...)利用类成员函数创建线程

    c++11是VS2012后支持的新标准,为并发编程提供了方便的std::thread. 使用示例: #include <thread> void thread_func(int arg1, ...

  4. C++ 面向对象 类成员函数this指针

    每个类成员函数都只涉及一个对象, 即调用它的对象. 但有时候方法可能涉及到两个对象, 在这种情况下需要使用C++ 的 this 指针 假设将方法命名为topval(), 则函数调用stock1.top ...

  5. 【非原创】C++类成员函数的重载、覆盖和隐藏

    链接:https://www.nowcoder.com/questionTerminal/266d3a6d4f1b436aabf1eff3156fed95来源:牛客网 题目:类成员函数的重载.覆盖和隐 ...

  6. 重载运算符:类成员函数or友元函数

    类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...

  7. C++类成员函数的重载、覆盖和隐藏区别?

    C++类成员函数的重载.覆盖和隐藏区别? a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:(4)virtual 关键字可有可无.b.覆盖是指派生类函数覆 ...

  8. C++:类成员函数的重载、覆盖和隐藏区别?

    #include <iostream> class A { public: void func() { std::cout << "Hello" <& ...

  9. 类成员函数的重载、覆盖和隐藏区别 (C++)(转)

    类成员函数的重载.覆盖和隐藏区别 (C++)   这是本人第一次写博客,主要是想记录自己的学习过程.心得体会,一是可以方便以后回顾相关知识,二是可以与大家相互学习交流. 关于C++中类成员函数的重载. ...

随机推荐

  1. 如何把PDF文件转换为JPG图片

    大家有遇到需要将PDF文件转换为JPG的情况么,文档资料里面经常会有一些图片类型的内容,有的时候我们需要获取这些图片内容,但是PDF文件又是不可编辑的,那如何把PDF文件转换为JPG图片呢,跟着小编一 ...

  2. 5.5 Components -- Customizing A Compnent's Element

    一.概述 默认的,每一个组件都基于一个<div>元素.如果你在开发者工具中查看一个渲染的组件,你将会看到一个像这样的DOM表示: <div id="ember180&quo ...

  3. Vim简明教程【CoolShell】(转)

    m的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progressiv ...

  4. node学习笔记第一天

    ES6---* JavaScript语言随着使用的人越来越多,ECMA语法规范:if/else* 为了让js语言更适应大型应用的开发.旨在消除一些怪异的行为 ### 包含内容(strict严格模式)- ...

  5. Vue学习笔记之vue-cli脚手架项目中组件的使用

    在webpack-simple模板中,包括webpck模板.一个.vue文件就是一个组件. 为什么会这样呢?因为webpack干活了!webpack的将我们所有的资源文件进行打包.同时webpack还 ...

  6. STM32组合设备实现USB转双串口

    USB转双串口,核心技术就在于组合设备(USB Composite)的实现,组合设备的实现,其核心技术在于描述符的实现,下面我们先给出描述符:设备描述符 [C] 纯文本查看 复制代码 ? 00001 ...

  7. Java Mail 邮件发送简单封装

    上一篇文章我们用写了一个Java Mail 的Demo,相信你已经可以用那个例子来发送邮件了.但是Demo 有很多的问题. 首先每次发送需要配置的东西很多,包括发件人的邮箱和密码.smtp服务器和SM ...

  8. BZOJ 1042: [HAOI2008]硬币购物(容斥原理)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1042 题意: 思路: 如果不考虑硬币个数的话,这就是一道完全背包的题目. 直接求的话行不通,于是这里 ...

  9. POJ 2112 Optimal Milking(二分+最大流)

    http://poj.org/problem?id=2112 题意: 现在有K台挤奶器和C头奶牛,奶牛和挤奶器之间有距离,每台挤奶器每天最多为M头奶挤奶,现在要安排路程,使得C头奶牛所走的路程中的最大 ...

  10. POJ 2762 Going from u to v or from v to u? (判断单连通)

    http://poj.org/problem?id=2762 题意:给出有向图,判断任意两个点u和v,是否可以从u到v或者从v到u. 思路: 判断图是否是单连通的. 首先来一遍强连通缩点,重新建立新图 ...