免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3879 | 回复: 5
打印 上一主题 下一主题

[C++] 关于getter和setter方法的const属性 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-10-29 11:18 |只看该作者 |倒序浏览
本帖最后由 vesontio 于 2014-10-29 11:22 编辑

我声明一个类
  1. #include <string>

  2. #ifndef CLASS_STUDENT
  3. #define CLASS_STUDENT

  4. class Student {
  5.   public:
  6.     Student(const std::string &fn, const std::string &ln, int a) :
  7.      firstName(fn), lastName(ln), age(a) {}
  8.     void setFirstName(const std::string &);
  9.     void setLastName(const std::string &);
  10.     void setAge(unsigned);
  11.     std::string getFirstName() const;
  12.     std::string getLastName() const;
  13.     unsigned getAge() const;
  14.   private:
  15.     std::string firstName;
  16.     std::string lastName;
  17.     unsigned age;
  18. };
  19. #endif
复制代码
现在的问题是,所有的getter都必须为const,《C++ Primer》的解释是,所有的类方法都被默认添加指针Student *const this,每当我们操作类的属性时,都是通过这个隐性指针进行的。
那this不可以被赋以非const的。那作为getter,本身就不应该改动对象内的属性,对象应当是一个const,所以this的真正类型应当是const Student *const,所以就通过在声明末尾添加const来实现。

但是setter,例如seetFirstName(const std::string &),也被默认添加指针Student *const this,但是因为我们需要给类的属性赋值,所以这时候,对象不是const,所以this的类型是OK的。

我的疑问是,编译器怎么知道当前操作的对象是否是const,当前对象的const属性是可以变的吗?呼叫getter的时候,它就变成const,呼叫setter的时候,它就不是了?

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
2 [报告]
发表于 2014-10-29 13:04 |只看该作者
std::string getFirstName() const;

这个const修饰的是getFirstName这个方法,并不是该方法所在的类或该类的某个运行时对象。

换句话说,编译器检查的是getFirstName里面,有没有任何可能修改this指针指向内容的动作,如果有,就报错,根本不关心给它传的this指针是什么属性。



同样的,setter方法,编译器不关心这个方法内部做了什么,只关心传给它的this指针不能是const。


换句话说,const的getter方法的检查,是在该方法被编译时;而非const的setter方法的检查,则是在程序里面每个setter方法的调用点。

论坛徽章:
0
3 [报告]
发表于 2014-10-29 13:31 |只看该作者
shan_ghost 发表于 2014-10-29 13:04
std::string getFirstName() const;

这个const修饰的是getFirstName这个方法,并不是该方法所在的类或该 ...


恩,谢谢,大概明白了。又写了个测试方法:
  1. std::string testMethod(const std::string &) ;

  2. std::string Student::testMethod(const std::string &s) {
  3.   firstName = s;
  4.   return lastName;
  5. }
复制代码
如果我为它添加const修饰,gcc就报错,如果不添加就OK。也就是说,编译器检测到我有赋值操作(=),所以单独针对该方法,要求禁用const修饰?

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
4 [报告]
发表于 2014-10-29 13:51 |只看该作者
本帖最后由 shan_ghost 于 2014-10-29 14:04 编辑

1、const方法不得修改类成员变量

2、如果有类似“记录某类getter被调用次数”之类需求,可声明一个mutable 成员:

class test
{
public:
  void testMethod() const;
private:
  mutable int times;
}

这个times成员变量就允许const方法修改其值。

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
5 [报告]
发表于 2014-10-29 14:02 |只看该作者

论坛徽章:
0
6 [报告]
发表于 2014-10-29 14:38 |只看该作者
shan_ghost 发表于 2014-10-29 13:51
1、const方法不得修改类成员变量

2、如果有类似“记录某类getter被调用次数”之类需求,可声明一个mutab ...


明白很多了,谢谢楼上的耐心回复。其他更多的经验得在实际练习中积累了。再次感谢。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP