经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C++ 之 常量成员函数
来源:cnblogs  作者:飞鸢逐浪  时间:2021/12/20 15:55:25  对本文有异议

1  const 后缀    

    成员函数,在参数列表之后加 const,可声明为 常量成员函数,即该函数对于成员变量,只可读不可写 

    例如,Date 类中的三个常量成员函数:GetYear()、GetMonth() 和 GetDay() 

  1. class Date {
  2. public:
  3. int GetYear() const { return y; }
  4.   int GetMonth() const { return m; }
  5. int GetDay() const { return d; }
  6. void AddYear(int n); // add n years
  7. private:
  8. int y, m, d;
  9. };    

     当在 GetYear() 中,修改成员变量 y 时,编译会报错 

  1. // error : attempt to change member value in const function
  2. int Date::GetYear() const
  3. {
  4. return ++y;
  5. }      

    注意 1):常量成员函数,在类外实现时,const 后缀不可省略

  1. // error : const missing in member function type
  2. int Date::GetYear()
  3. {
  4. return y;
  5. }

    注意 2):成员变量前有 mutable,则在常量成员函数中,也可修改成员变量

  1. class Date {
  2. // ...
  3. private:
  4. mutable int y
  5. }; 
  6.  
  7. // ok, even changing member value in const function
  8. int Date::GetYear()
  9. {
  10. return ++y;
  11. }  

   

2  this 指针

    const 成员函数,可被 const 或 non-const 型类对象调用,如 GetYear(),而 non-const 成员函数,只能被 non-const 对象调用,如 AddYear() 

  1. void func(Date& d, const Date& cd)
  2. {
  3. int i = d.GetYear(); // OK
  4. d.AddYear(1); // OK
  5.  
  6. int j = cd.GetYear(); // OK
  7. cd.AddYear(1); // error
  8. }     

    任何成员函数,都有一个隐含的形参,即指向该类对象的 this 指针,它通常由编译器隐式的生成,通过 this 指针,类对象才能调用成员函数

    一般的,this 指针默认指向 non-const 对象,因此,const 类对象,无法通过 this 指针调用 non-const 函数 

  1. // 默认的 this 指针,指向 non-const 对象
  2. Date * const this;  

    而 const 成员函数,通过参数后的 const 后缀,修改其 this 指针指向 const 型对象,此时,const 对象便可调用 const 成员函数

  1. // 常量成员函数中的 this 指针,指向 const 对象
  2. const Date * const this;

  

3  const 接口

   上文的 func() 函数中,形参用 const 来修饰,可保证数据传递给函数,而本身不被修改,是设计 "接口" 的一种常用形式

  1. void func(Date& d, const Date& cd)
  2. {
  3. // ... ...
  4. } 

    特殊情况下,想要 const 对象调用 non-const 成员函数,则可用 const_cast 移除对象的 const 属性,具体形式为:  const_cast<T>(expression) 

  1. void func(Date& d, const Date& cd)
  2. {
  3. int j = cd.GetYear(); // OK
  4. const_cast<Date&>(cd).AddYear(1); // const 对象调用 non-const 成员函数
  5. }  

    这种做法,破坏了用 const 来指定 "接口" 的本意,并不推荐

 

参考资料

 《C++ Programming Language》4th ch 16.2.9.1

 《C++ Primer》5th ch 7.1.2

 《Effective C++》3rd Item 3, item 27

 《More Effective C++》 Item 2

 

原文链接: http://www.cnblogs.com/xinxue/

专注于机器视觉、OpenCV、C++ 编程

原文链接:http://www.cnblogs.com/xinxue/p/15706758.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号