类4(可变数据成员/基于const的重载)
可变数据成员:
有时我们希望能修改某个类的数据成员,即使是在一个 const 成员函数内。可以通过在变量的声明中加入 mutable 关键字来声明一个可变数据成员。mutable 是为突破 const 的限制而设置的。被 mutable 修饰的变量将永远处于可变状态中,即使是在一个 const 成员函数中:
#include <iostream>
using namespace std; class gel{
private:
mutable size_t access_ctr; public:
gel() = default;
gel(const int &x):access_ctr(x){}
// ~gel(); void out_put() const{
cout << access_ctr << endl;
} void some_member(void) const{
++access_ctr;
}
}; int main(void){
const gel x();
x.out_put();//输出1
x.some_member();
x.out_put();//输出2
x.some_member();
x.out_put();//输出3
return ;
}
关于 mutable 关键字存在的必要性:https://www.zhihu.com/question/64969053/answer/226383958
基于 const 的重载:
#include <iostream>
using namespace std; class gel{
private:
int x; public:
gel() = default;
gel(int val): x(val){} const gel &display(std::ostream &os) const{
std::cout << x;
return *this;
} gel &count(void){
x++;
return *this;
}
}; int main(void){
gel x();
x.display(cout);
x.count();
// x.display(cout).count();//错误:display 返回的是一个 const 对象,而 count 不是常量函数
return ;
}
一般来说像 x.display(cout); 与 x.count(); 应该是要可以写成 x.display(cout).count();的形式的。但这个代码中 display 返回的是一个 const 对象,所以后者显然是错误的。这是我们代码写的不合理,应该尽量避免写出这样的代码。我们可以通过重载解决这个问题:
#include <iostream>
using namespace std; class gel{
private:
int x; public:
gel() = default;
gel(int val): x(val){} gel &display(std::ostream &os){
do_display(os);
// os << x;//在代码比较短的时候这样写也一样,不过要是代码量大的话显然要多写不少代码
return *this;
} const gel &display(std::ostream &os) const{
do_display(os);
// os << x;
return *this;
} gel &count(void){
x++;
return *this;
} private:
void do_display(std::ostream &os) const{
os << x;
}
}; int main(void){
gel x();
x.display(cout).count();
return ;
}
这里我们通过调用 display 的对象是否为常量来决定调用哪个 display 函数。需要注意的是这里是通过底层 const 来区分重载函数的(形参会忽略顶层 const),若调用 display 的对象是 const,那么隐式传递的 this 指针具有底层 const,反之则没有。
调用 display 的是非常量的话,display 返回的也是一个非常量对象,此时 x.display(cout).count();顺利执行;
调用 display 的是常量的话, display 返回的也是一个常量对象,此时 x.display(cout).count();报错。
显然,这个代码中的 x.display(cout).count();与 x.display(cout);x.count();是完全等价的。
类4(可变数据成员/基于const的重载)的更多相关文章
- static数据成员与const数据成员的定义与初始化
三种数据类型的初始化 1.static int a 的初始化 const int a 的初始化 static const int a的初始化 三种初始化方式 在类外初始化 在构造函数中通过初始化列表初 ...
- C++ 学习之函数重载、基于const的重载
函数重载 函数重载的定义是:在相同的作用域中,如果函数具有相同名字而仅仅是形参表不同,此时成为函数重载.注意函数重载不能基于不同的返回值类型进行重载. 注意函数重载中的"形参表"不 ...
- Cocos2d-x 3.1.1 学习日志3--C++ 初始化类的常量数据成员、静态数据成员、常量静态数据成员
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u011292087/article/details/37598919 有关const成员.stati ...
- 编写一个矩形类,私有数据成员为矩形的长( len)和宽(wid),wid设置为0,有参构造函数设置和的值,另外,类还包括矩形的周长、求面积、取矩形的长度、取矩形的长度、取矩形的宽度、修改矩形的长度和宽度为对应的形参值等公用方法。
class Rectangle { private double len, wid; public Rectangle()//求矩形周长 { len = 0; wid = 0; } public Re ...
- C++类中静态数据成员MAP如何初始化
conv_xxx.hpp class convolution { ... ... typedef std::map<int, std::string> ConvDtMap; static ...
- 如何导出标准模板库(STL)类的实例化和包含STL类对象数据成员的类
本文翻译自 https://support.microsoft.com/zh-cn/help/168958/how-to-export-an-instantiation-of-a-standard-t ...
- 正确理解Widget::Widget(QWidget *parent) :QWidget(parent)这句话(初始化列表中无法直接初始化基类的数据成员,所以你需要在列表中指定基类的构造函数)
最近有点忙,先发一篇我公众号的文章,以下是原文. /********原文********/ 最近很多学习Qt的小伙伴在我的微信公众号私信我,该如何理解下面段代码的第二行QWidget(parent) ...
- 转:C语言中的static变量和C++静态数据成员(static member)
转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量 a.静态局部变量在函数内定义,生存期为整个程序 ...
- C++:用成员初始化列表对数据成员初始化
1.在声明类时,对数据成员的初始化工作一般在构造函数中用赋值语句进行. 例如: class Complex{ private: double real; double imag; public: Co ...
随机推荐
- 7.solr学习速成之facet
Facet 介绍 Facet 是 solr 的高级搜索功能之一 ,可以给用户提供更友好的搜索体验,在搜索关键字的同时 , 能够按照 Facet 的字段进行分组并统计. 比如你上淘宝, ...
- 【树莓派】开机自启动脚本方法之一(.Desktop文件)
转载处: 又一个让树莓派开机运行Python脚本的方法 Linux 创建启动器(.Desktop文件) 首先,树莓派使用的是官方推荐的镜像:RASPBIAN: 在树莓派上常常会需要开机自启动pytho ...
- ndnarry元素处理
元素计算函数 ceil(): 向上最接近的整数,参数是 number 或 array floor(): 向下最接近的整数,参数是 number 或 array rint(): 四舍五入,参数是 num ...
- leetcode896
class Solution { public: bool isMonotonic(vector<int>& A) { ) { return true; } bool GetDif ...
- Delphi IOS 蓝牙锁屏后台运行
Delphi IOS 后台运行 同样的程序,编译成android,锁屏后继续运行正常,蓝牙通讯正常,但在IOS下锁屏后程序的蓝牙就中断通讯了? IOS的机制就是这样,锁屏就关闭了. 音乐播放器是怎么做 ...
- Hadoop Serialization -- hadoop序列化详解 (3)【ObjectWritable,集合Writable以及自定义的Writable】
前瞻:本文介绍ObjectWritable,集合Writable以及自定义的Writable TextPair 回顾: 前面了解到hadoop本身支持java的基本类型的序列化,并且提供相应的包装实现 ...
- 详解PHP执行定时任务的实现思路
PHP本身是没有定时功能的,PHP也不能多线程.PHP的定时任务功能必须通过和其他工具结合才能实现,例如WordPress内置了wp-cron的功能,很厉害. 一.Linux服务器上使用CronTab ...
- java socket发送xml报文
ServerRun.java import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; pub ...
- Oracle & SQL Server 数据传输
在开发中用到的Oracle与SQL Server间数据传输的不同方法的整理,比较.包括原理的简介,配置和实现方法,优缺点的比较,使用平台和DB,适合的应用范围和效能的比较. 整理的方法有如下六种: 1 ...
- LoadRunner 关联和集合点、检查点
1)关联的定义 很多时候,当时录完之后,没有问题.过一段时间再跑脚本,就不会成功.比如session,过期了,再一次使用,就会出错.这个时候,需要在每次访问的时候动态的拿到session,这种情况就需 ...