const学习(续)
续接上一篇《C++ const学习》
const与成员函数
之前说到了const修饰成员函数本身。
- const成员函数不能修改对象成员值
- 对于const或者费const对象都可以调用const成员函数,而非const成员函数则只能对非const对象调用
那现在就有三个问题:
- const能否修饰非成员函数?
- const修饰成员函数能否和static一起使用?
- const函数中是否可以修改static成员的值?
- 在实际情况中需要const成员函数修改没个成员的值呢?如果有,该如何处理?
class ClassB
{
public:
static int s_a;
string a;
static void funB() const; //2.??
void funC() const
{
s_a = ; //3.??
a = "xx"; //4.??
}
};
对于问题一,假设非成员函数可以被const修改,那是要限定什么值不能修改呢?全局?而且这个const函数是对谁提供的呢?好像我们并不能找到合适的答案。所以funA(),编译时不通过,error:非成员函数不允许使用限定符。也就是说在C中不存在const限定函数这种情形。
问题二其实和问题一是一样的,static成员函数属于类,并不属于某个对象。同样编译给出的error: 静态成员函数上不允许修饰符。
问题三和二一样,可以修改static成员值。
对于问题四,就要先看实际中有没有这种可能。暂时没想到合适的例子,就直接copy《The c++ Programming Language》书上的缓存了。在经常读取某些复杂的数据结构时,如将对象转化为string,为了提高效率,就用到了缓存,这个转换的过程ToString()只可能对缓存cache做修改,而不修改对象的其他成员值。此时就存在了ToString() const修改cache这个值。
这里就分为物理常量(physical constness\bitwise constness)和逻辑常量(logical constness)。物理常量其实就是const常量性的定义,因此不可修改对象的任何成员的值。而逻辑常量就是问题四中那种形式,客户端侦测不出可以修改的变量,如cache。
此时可以将const转化为non-const,运用const_cast
class ClassB
{
public:
string a;
void funC() const
{
ClassB * nonConstb= const_cast<ClassB *>(this);
nonConstb->a="xx"; cout<<"nonConstb:"<<nonConstb<<endl;
cout<<"this:"<<this<<endl;
}
}; int _tmain(int argc, _TCHAR* argv[])
{ ClassB cb;
cb.funC();
cout<<cb.a.c_str();
}
运行结果为:
nonConstb:0015FB58
this:0015FB58
xx
请按任意键继续. . .
通过代码及运行结果可以看出:
- 非const对象隐式的转化为const对象,再调用const成员函数
- const_cast类型转换时,对象地址不变,将在const成员函数中将const对象指针this,转化为non-constd对象指针nonConstb
《Effective c++》中提到的转型是一个糟糕的想法,如条款27(目前还没看到这里,先不详谈,个人认识所有的转型都有信息的丢失,且有些是不可逆的)
mutable释放掉non-static成员变量的bitwise constness约束:
class ClassB
{
public:
string a;
mutable string b;
void funC() const
{
b="yyy";
}
};
int _tmain(int argc, _TCHAR* argv[])
{ ClassB cb;
cb.funC();
cout<<cb.b.c_str()<<endl;
}
输出结果:yyy
ok,到目前为止,把关于const的只是整理学习了下。
在实际代码中个人偏好是:
- 能用const就一定要用const。因为用了不会错,不用可能出错,而且编译器可以帮助检出某些人为的疏忽错误
- const可以帮助软件的设计与代码书写着沟通。个人最喜欢的就是将可为const的函数参数一定限定为const,由于以前在做C#的时候一直没找到一个好的方法,限定函数内部不要修改传过来的参数值
- 减少代码中的各种文字常量,与一些莫名其妙的数值与字串
- 还有个原因,个人是从C#转过来的,不习惯运用宏定义常量
const学习(续)的更多相关文章
- yield学习续:yield return迭代块在Unity3D中的应用——协程
必读好文推荐: Unity协程(Coroutine)原理深入剖析 Unity协程(Coroutine)原理深入剖析再续 上面的文章说得太透彻,所以这里就记一下自己的学习笔记了. 首先要说明的是,协程并 ...
- ES6 let const学习
1.let命令:用法类似于var,但是所声明的变量,只在let命令所在的代码块有效. 例:var a = [ ]; for(var i=0;i<10;i++){ a[ i ] = functio ...
- const 学习笔记
#include<stdlib.h> #include<iostream> using namespace std; int main(){ // const 仅仅起到是否为常 ...
- 树莓派 -- i2c学习 续(1) DeviceTree Overlay实例化rtc
上文中讨论了通过sysfs来实例化i2c设备 (rtc ds3231) https://blog.csdn.net/feiwatson/article/details/81048616 本文继续看看如 ...
- C++ const学习
概念 const就是为了直接表达“不变化的值”这一概念.也就是说该值只可读,不可直接写. 由于不可以修改,所以const常量在声明的时候必须初始化 const int a; //error exter ...
- CSS定位走一波(定位学习续)
又是新的一周过去了,时间到了,春天绿了,关于HTML5的学习进步了,今天博客更新一些CSS定位的内容,小的一些细节也要牢记,方便做一个更完美的项目. 如何让垂直方向居中,解决方式:在父元素添加over ...
- 委托学习续:Action、Func和Predicate
我们先看一个上一章的委托的例子: using System; using System.Collections.Generic; using System.Linq; using System.Tex ...
- html 标签学习(续)
一.基础标签补充 1.div 标签和span标签 (没有特别的样式,常用) div标签用来定义一个块级元素,并无实际的意义.主要通过CSS样式为其赋予不同的表现. span标签用来定义内联(行内)元素 ...
- Kubernetes学习续之一键部署kubeadm
1.Kubernetes的架构和组件,在部署时,它的每一个组件都是一个需要被执行的.单独的二进制文件,所以不难想象,SaltStack这样的运维工具或由社区维护的脚本的功能,就是要把这些二进制文件传输 ...
随机推荐
- 更新数据库中数据时出现: Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences 问题
使用workbench在数据库中更新数据时报错: You are using safe update mode and you tried to update a table without a WH ...
- Ubuntu 16.04下搭建基于携程Apollo(阿波罗)配置中心单机模式
官网:https://github.com/ctripcorp/apollo Wiki:https://github.com/ctripcorp/apollo/wiki(一切的集成方式和使用方法都在这 ...
- server证书安装配置指南(Tomcat 6)
一. 生成证书请求 1. 安装JDK 安装Tomcat须要JDK支持. 假设您还没有JDK的安装.则能够參考 Java SE Development Kit (JDK) 下载. 下载地址: ...
- Android.mk文件解析
一.一个简单的Android.mk文件例如以下: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := nativ ...
- Android系统优化
这些事实上就是优化rom 的一些实用小技巧. 认为非常多还是实用的. Build.prop (编辑 /system/build.prop 文件(须要root, 能够用文件管理器或者其它root exp ...
- [项目机会]使用lync的统一通信平台
[项目内容]基于微软的lync或者其他思科.腾讯等公司技术,建立一个员工统一的通讯平台,可以随时的保持员工之间沟通. [项目价值] 1.保持项目团队成员之间的随时随地高效的电话或者视频会议: 2.集成 ...
- HDU 5000 2014 ACM/ICPC Asia Regional Anshan Online DP
Clone Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other) Total Submiss ...
- NTFS文件系统的单个文件最大到底有多大?
于NTFS文件系统的单个文件最大到底有多大? 闲来无事突然想到这个问题,到网上搜索了一下也没有一个固定的解释. 于是到微软官方知识库去寻找答案: 注意:基础硬件限制可能会对任何文件系统施加额外的分区大 ...
- 怎么在当前的view上获取所在的控制器(UIViewController),实现跳转
- (UIViewController *)viewController { for (UIView* next = [self superview]; next; next = next.super ...
- 基于Spark和Tensorflow构建DCN模型进行CTR预测
实验介绍 数据采用Criteo Display Ads.这个数据一共11G,有13个integer features,26个categorical features. Spark 由于数据比较大,且只 ...