浏览 2375 次
锁定老帖子 主题:条款21: 尽可能使用const
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-02-10
先提下有个陷阱,比如 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; } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |