打破C++ Const 的规则
从一个C++菜鸟改函数开始
CString MyClass::GetStringValue() const
{
return m_strValue;
}
这个值可能还没有赋值,好吧,那么我先判断是不是为空,为空就赋值了
CString MyClass::GetStringValue() const
{
if(m_strValue.IsEmpty())
SetStringValue(); return m_strValue;
}
结果,编译就不过,因为有个规则:const函数里面不能调用非const函数。
看到下面的编译错误:
error C2662: “MyClass::SetStringValue”: 不能将“this”指针从“const MyClass”转换为“MyClass &”
嘿嘿原来是这样:当我们定义了一个类的成员函数会默认传进来一个this指针,但是如果是一个const 函数那么是不是就传竟来一个const的指针呢?所以我想编译器看到是这样的:
CString MyClass::GetStringValue(const MyClass* this)
{
if(this->m_strValue.IsEmpty())
this->SetStringValue(); return this->GetStringValue();
}
后来验证一下,创建了一个static函数模拟一下:
CString MyClass::GetStringValueS(const MyClass* mcp)
{
if(mcp->m_strValue.IsEmpty())
mcp->SetStringValue(); return mcp->GetStringValue();
}
编译真的得到一个同样的错误:
error C2662: “MyClass::SetStringValue”: 不能将“this”指针从“const MyClass”转换为“MyClass &”
所以我试着去打破const规则:
CString MyClass::GetStringValue()const
{
MyClass * nonconstthis = (MyClass *)this;
if(m_strValue.IsEmpty())
nonconstthis->SetStringValue(); return m_strValue;
}
结果编译通过,执行也没有问题。
所以有一个转换const_cast<>专门来做这样的事情:
CString MyClass::GetStringValue()const
{
if(m_strValue.IsEmpty())
const_cast<MyClass *>(this)->SetStringValue(); return m_strValue;
}
最后,我认为,这样违背了const设计的初衷,这样对于调用者是一种欺骗(违背契约:我保证不改你),所以不推荐这样使用。
打破C++ Const 的规则的更多相关文章
- const修饰规则 及其 用法
const指针和指向const变量的指针,在写法上容易让人混淆,记住一个规则:从左至右,依次结合,const就近结合. 比如,int * const p: 1.int * (const p):变量p经 ...
- 【转】CSS样式覆盖规则
大家都知道CSS的全称叫做“层叠样式表”,但估计很多人都不知道“层叠”二字的含义.其实,“层叠”指的就是样式的覆盖,当一个元素被运用上多种样式,并且出现重名的样式属性时,浏览器必须从中选择一个属性值, ...
- (转) C/C++中const关键字详解
文章转自 http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html 为什么使用const?采用符号常量写出的代码更容易维 ...
- c/c++中const使用总结(金典)
原文地址:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html 个人总结: (1)const只对它左 ...
- c++的const总结
转自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html 为什么使用const?采用符号常量写出的代码更容易维护:指 ...
- C#命名规则和风格(收集)
1. 文件命名组织 1-1文件命名 1. 文件名遵从Pascal命名法,无特殊情况,扩展名小写. 2. 使用统一而又通用的文件扩展名: C# 类 .cs 1-2文件 ...
- [C++] CONST 2
The C++ 'const' Declaration: Why & How The 'const' system is one of the really messy features of ...
- CSS样式:覆盖规则
规则一:由于继承而发生样式冲突时,最近祖先获胜. CSS的继承机制使得元素可以从包含它的祖先元素中继承样式,考虑下面这种情况: <html> <head> <title& ...
- const关键字祥解
为什么使用const?采用符号常量写出的代码更容易维护:指针常常是边读边移动,而不是边写边移动:许多函数参数是只读不写的.const最常见用途是作为数组的界和switch分情况标号(也可以用枚举符代替 ...
随机推荐
- php 被抛弃使用的函数
call_user_method()(使用 call_user_func() 替代) call_user_method_array() (使用 call_user_func_array() 替 ...
- Visual Studio调试之断点进阶篇
Visual Studio调试之断点进阶篇 在上一篇文章Visual Studio调试之断点基础篇里面介绍了什么是断点,INT 是Intel系列CPU的一个指令,可以让程序产生一个中断或者异常.程序中 ...
- winform中WebBrowser控件执行脚本
在实际应用中我们可能需要WebBrowser控件主动执行我们需要的脚本,执行脚本现在有两种方法. 1.WebBrowser控件加载脚本,简单方便,适用于简短的脚本,无法执行复杂操作. webBrows ...
- iOS NSDictionary、NSData、JSON等 数据类型相互转换
1.NSDictionary类型转换为NSData类型: NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: @&qu ...
- Sicily 1133. SPAM
题目地址:1133. SPAM 思路: 题目意思是说在‘@’的前后出现题目给定的合法字符或者不连续出现‘.’字符的话,这个就是合理的输出. 那么以@为中心,向前,向后扫描,当扫描到不符合字符时,记录此 ...
- Oracle 基本命令
(1)查看所有表 >select * from tab; (2)查看表结构 >desc 表名; (3)将查询出来的字段显示为其他名称 >select empno as 员工编号 fr ...
- Linux永久挂载远程网络目录
一般我们不永久挂载可以这样: mount -t cifs -o user=administrator,password=Fjqx2012,codepage=cp936,iocharset=cp936 ...
- 当分页语句遇到union all
SELECT * FROM (SELECT pubformdat0_.id id332_, pubformdat0_.domain_id domain2_332_, pubformdat0_.proc ...
- linux c 之signal 和sigaction区别
http://blog.csdn.net/muge0913/article/details/7331129 要对一个信号进行处理,就需要给出此信号发生时系统所调用的处理函数.可以对一个特定的信号(除去 ...
- HDU_2011——求多项式的前n项和
Problem Description 多项式的描述如下:1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + ...现在请你求出该多项式的前n项的和. Input 输入数据由2行组 ...