防止你做错事的冲动"const"!!
先提下有个陷阱,比如
typedef pC char*
void f1(pC const p)//好象是反的,记不清了
并不是所希望的char* const //指针常量,而是const char *p //常量指针;
例子好象是这样的吧,可以搜索typedef陷阱关键字。
那么在函数接口中像
class widget { ... };
void f1(const widget *pw); // f1取的是指向
// widget常量对象的指针
void f2(widget const *pw); // 同f1
都是等同的,都是一个指向常量的指针,
用const就像开头所说,防止许多错事发生,比如
(a * b) = c; // 对a*b的结果赋值
函数申明就得是
const rational operator*(const rational& lhs, const rational& rhs);
我还以为const也就这样了,但是接下来这个例子可能让你吓一跳,const在重载函数中的运用
class string {
public:
...
// 用于非const对象的operator[]
char& operator[](int position)
{ return data[position]; }
// 用于const对象的operator[]
const char& operator[](int position) const
{ return data[position]; }
private:
char *data;
};
string s1 = "hello";
cout << s1[0]; // 调用非const
// string::operator[]
const string s2 = "world";
cout << s2[0]; // 调用const
// string::operator[],这里语意我是这么理解的,既然s2本身是一个const,那么
//调用它的值自然也是const
通过重载operator[]并给不同版本不同的返回值,就可以对const和非const string进行不同的处理:
string s = "hello"; // 非const string对象
cout << s[0]; // 正确——读一个
// 非const string
s[0] = 'x'; // 正确——写一个
// 非const string
const string cs = "world"; // const string 对象
cout << cs[0]; // 正确——读一个
// const string
cs[0] = 'x'; // 错误!——写一个
// const string
还要注意在返回值上上引用类型的,否则cs[0]='x',结果是对一个局域变量赋值
接下来这章中讲了从语义和数据上来区分const函数对成员数据的修改以及mutable关键字,不是很有兴趣,不打算写代码调试
不过最后对const的总结很值得学习,最后自我总结下
const这个关键字从语义上来说不被修改,一个常量值。但是一些语法上的手脚可能会违背这个约定。比如你定义个类,定义了
一个数据A类型转换函数,并且设定成const。接着你用数据类型A定义了一个指针,指向这个类的某个实例。你会发现可以对它
修改了。 其次,还是从语义上来说,一些东西从外表看过去是不能被修改的,但是在内部还是需要修改或者赋一些值,怎么办
呢?只好用mutable关键字,从各种语法来约束它。
对const修改可有这样方法,
在外部,
class string {
public:
// 构造函数,使data指向一个
// value所指向的数据的拷贝
string(const char *value);
...
operator char *() const { return data;}
private:
char *data;
};
const string s = "hello"; // 声明常量对象
char *nasty = s; // 调用 operator char*() const
*nasty = 'm'; // 修改s.data[0]
cout << s; // 输出"mello"
在内部:
类的一个成员函数中,this指针就好象经过如下的声明:
c * const this; // 非const成员函数中
const c * const this; // const成员函数中
但可以通过初始化一个局部变量指针,使之指向this所指的同一个对象来间接实现。然后,就可以通过这个局部指针来访问你
想修改的成员:
size_t string::length() const
{
// 定义一个不指向const对象的
// 局部版本的this指针
string * const localthis =
const_cast<string * const>(this);
if (!lengthisvalid) {
localthis->datalength = strlen(data);
localthis->lengthisvalid = true;
}
return datalength;
}
分享到:
相关推荐
条款21: 尽可能使用const 条款22: 尽量用“传引用”而不用“传值” 条款23: 必须返回一个对象时不要试图返回一个引用 条款24: 在函数重载和设定参数缺省值间慎重选择 条款25: 避免对指针和数字类型重载 条款26: 当心...
条款21:尽可能使用CONST 条款22:尽量用传引用而不用传值 条款23:必须返回一个对象时不要试图返回一个引用 条款24:在函数重载与设定参数默认值间慎重选择 条款25:避免对指针与数字类型的重载 条款26:当心潜在的二义性...
CUJ:标准库:定义iterator和const iterator
目 录一.让自己习惯 C++ 1条款 03:尽可能使用 const 23)const 修饰成员函数 2条款 04:确定对象被使用前已先被初始化 4二.构造/析构
常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁换柱进行更新:) 2、为什么引入const? const 推出的初始目的,正是为了取代预编译指令,消除它的缺点...
条款03:尽可能使用const use const whenever possible. 条款04:确定对象被使用前已先被初始化 make sure that objects are initialized before they're used. 2. 构造/析构/赋值运算 constructors, destructors, ...
条款21: 永远让比较函数对相等的值返回false 条款22: 避免对set和multiset的键值进行修改 条款23: 考虑用排序的vector代替关联容器 条款24: 当效率很关键时尽量用map::insert代替map::operator 条款25: 让自己...
条款03:尽可能使用const 条款04:确定对象被使用前已先被初始化 2.构造/析构/赋值运算 条款05:了解C++默默编写并调用哪些函数 条款06:若不想使用编译器自动成生的函数,就该明确拒绝 条款07:为多态基类声明...
条款21:永远让比较函数对相等的值返回false 条款22:避免原地修改set和multiset的键 条款23:考虑使用有序vector代替关联容器 条款24:当关乎效率时应该在map::operator[]和map-insert之间仔细选择 条款25:...
条款21: 永远让比较函数对相等的值返回false 条款22: 避免对set和multiset的键值进行修改 条款23: 考虑用排序的vector代替关联容器 条款24: 当效率很关键时尽量用map::insert代替map::operator 条款25: 让自己...
{'long': 0.03660100303760025, 'lat': 0.5077259659824991, 'light': 21, 'const': 1}, {'long': 0.04004802831028905, 'lat': 1.0323574005393255, 'light': 23, 'const': 18}, {'long': 0.03944444109507185, '...
如何将vector和string的数据传给传统的API 条款17:使用“交换技巧”来修整过剩容量 条款18:避免使用vector<bool><br>关联容器 条款19:了解相等和等价的区别 条款20:为指针的关联容器指定比较类型...
EFFECTIVE C++ 条款03 尽量使用const 思维导图
C++中的各种Const用法小结:const常量,const 修饰类的数据成员等等
std::string、char*、const char*转托管byte数组或托管字符串String
徐彤老师耗时三年倾心制作,专业录制,通俗,细致的讲解了C++ 编程从入门到高级
C++:浅谈修饰符const 魔鬼作坊学游戏辅助制作 moguizuofang.com
徐彤老师耗时三年倾心制作,专业录制,通俗,细致的讲解了C++ 编程从入门到高级
该文件是建立在排序树的基础之上的,该文件介绍如下: 该文件文件名为"BBTree.hpp",可以使元素从小到大进行排列,说明如下: //*以下内容为BBTree基础代码,其中: ...按照说明使用变量可实现任何类型数值从小到大排列
B样条的英文资料, 自由曲面建模的相关自理……………………