重载[]运算符,当作右值时不调用const成员函数

蓝猫淘气 2016-03-31 10:58:35
C++primer书上意思是做右值时自动调用const成员函数,但是实验看到结果还是调用重载的下标运算符的普通成员函数,返回引用。
如果调用下标运算符做右值时不调用const成员函数,而是普通成员函数,返回引用,那就会访问到私有成员变量,破坏封装性呀。

Primer.hpp
class CheckoutRecord{
friend ostream& operator<<(ostream&, const CheckoutRecord&);
friend istream& operator>>(istream&, CheckoutRecord&);
public:
typedef vector<pair<string, string>*>::size_type size_type;
CheckoutRecord(double d = 0,
string t = "NULL",
Date d1 = Date(),
Date d2 = Date()):
book_id(d), title(t), date_borrowed(d1), date_due(d2){}
pair<string, string>& operator[](size_type i);
const pair<string, string>& operator[](const size_t i) const;
private:
double book_id;
string title;
Date date_borrowed;
Date date_due;
pair<string, string> borrower;
vector<pair<string, string>*> wait_list;
};

Primer.cpp

const pair<string, string>&
CheckoutRecord::operator[](const size_t i) const{
cout << "const pair<string, string>& CheckoutRecord::operator[](size_t i)" << endl;
return *wait_list[i];
}

pair<string, string>&
CheckoutRecord::operator[](size_t i){
cout << "pair<string, string>& CheckoutRecord::operator[](size_t i)" << endl;
return *wait_list[i];
}


main.cpp

CheckoutRecord obj1;
readFile(obj1);
cout << obj1;
cout << obj1[2].first << "," << obj1[2].second << endl;
pair<string, string>* val = &obj1[1];
val->first = "hu";
cout << obj1 << endl;


结果

book_id:787001 title:cprimer, 2016-1-1, 2016-4-1, wang xin
li, shumeng
li, bo
pan, ji
zhu, xiantan
pair<string, string>& CheckoutRecord::operator[](size_t i)
pan,pair<string, string>& CheckoutRecord::operator[](size_t i)
ji
pair<string, string>& CheckoutRecord::operator[](size_t i)
book_id:787001 title:cprimer, 2016-1-1, 2016-4-1, wang xin
li, shumeng
hu, bo
pan, ji
zhu, xiantan

Program ended with exit code: 0
...全文
152 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdghchj 2016-03-31
  • 打赏
  • 举报
回复
返回值类型本身不同都不构成重载,前面加const就更不必说了。
sdghchj 2016-03-31
  • 打赏
  • 举报
回复
引用 2 楼 sdghchj 的回复:
返回的都是引用,不管是否是const引用,只要是引用就是左值。 左右值区分不是按在=的左右边,是看是否可以对其取地址符后进行正常地址操作。 所以返回值类型前是否加const没什么区别,你可以把参数上的const和函数后的const去掉后,看编译能通过否。 而对于函数参数为传值方式时,参数前加const也没意义。
说错了一点,返回值类型前加const与不加const不能构成重载,不是没有区别。
sdghchj 2016-03-31
  • 打赏
  • 举报
回复
返回的都是引用,不管是否是const引用,只要是引用就是左值。 左右值区分不是按在=的左右边,是看是否可以对其取地址符后进行正常地址操作。 所以返回值类型前是否加const没什么区别,你可以把参数上的const和函数后的const去掉后,看编译能通过否。 而对于函数参数为传值方式时,参数前加const也没意义。
fefe82 2016-03-31
  • 打赏
  • 举报
回复
右值会调用 const 版本,但不是说放在等号右边就是右值。 一个表达式的结果与它放在哪没什么关系。 但这个结果可能根据其所处的位置发生一些(类型)转换。
蓝猫淘气 2016-03-31
  • 打赏
  • 举报
回复
引用 6 楼 sdghchj 的回复:
[quote=引用 5 楼 qq_18492651 的回复:] 谢谢各位前辈的回答,另外小弟还有几个问题: 1.使用
const pair<string, string>& operator[](const size_t i) const;
时是看类实例化后的对象是否是const的,与例子中的obj1是否是const有关,而与val无关,也与是否是在等号左右无关。这样理解对吗? 2.对于
const pair<string, string>& operator[](const size_t i) const;
第一个const指明返回const引用,第三个const指明函数签名,使其能够重载返回非const引用版本[]运算符,那么第二个,也就是const size_t i的const在这有什么含义呢? 3. 何时调用
const pair<string, string>& operator[](const size_t i) const;
版本呢?
简单说,你的两个函数中,只有函数签名后的const能构成重载。传入参数是传值方式,const没实际意义。 什么时候调用会返回const类型的呢?显然就需要利用函数签名上的即第三个const的性质了,不能改变调用对象本身了,那就只能是调用者有const属性了,即要么你的obj1本身是const,要么是一个它的const&。 CheckoutRecord obj1; readFile(obj1); cout << obj1; const CheckoutRecord& obj2 = obj1; cout << obj2[0].first << "," << obj2[0].second << endl; 参数上的const即你的第2个const只有在引用传参时才有意义,const int&能接受一个临时变量或匿名对象,而int&不能,所以可构成重载。 [/quote] 谢谢您的解答,对于重载有更深的理解了。
sdghchj 2016-03-31
  • 打赏
  • 举报
回复
引用 5 楼 qq_18492651 的回复:
谢谢各位前辈的回答,另外小弟还有几个问题: 1.使用
const pair<string, string>& operator[](const size_t i) const;
时是看类实例化后的对象是否是const的,与例子中的obj1是否是const有关,而与val无关,也与是否是在等号左右无关。这样理解对吗? 2.对于
const pair<string, string>& operator[](const size_t i) const;
第一个const指明返回const引用,第三个const指明函数签名,使其能够重载返回非const引用版本[]运算符,那么第二个,也就是const size_t i的const在这有什么含义呢? 3. 何时调用
const pair<string, string>& operator[](const size_t i) const;
版本呢?
简单说,你的两个函数中,只有函数签名后的const能构成重载。传入参数是传值方式,const没实际意义。 什么时候调用会返回const类型的呢?显然就需要利用函数签名上的即第三个const的性质了,不能改变调用对象本身了,那就只能是调用者有const属性了,即要么你的obj1本身是const,要么是一个它的const&。 CheckoutRecord obj1; readFile(obj1); cout << obj1; const CheckoutRecord& obj2 = obj1; cout << obj2[0].first << "," << obj2[0].second << endl; 参数上的const即你的第2个const只有在引用传参时才有意义,const int&能接受一个临时变量或匿名对象,而int&不能,所以可构成重载。
蓝猫淘气 2016-03-31
  • 打赏
  • 举报
回复
谢谢各位前辈的回答,另外小弟还有几个问题: 1.使用
const pair<string, string>& operator[](const size_t i) const;
时是看类实例化后的对象是否是const的,与例子中的obj1是否是const有关,而与val无关,也与是否是在等号左右无关。这样理解对吗? 2.对于
const pair<string, string>& operator[](const size_t i) const;
第一个const指明返回const引用,第三个const指明函数签名,使其能够重载返回非const引用版本[]运算符,那么第二个,也就是const size_t i的const在这有什么含义呢? 3. 何时调用
const pair<string, string>& operator[](const size_t i) const;
版本呢?

65,189

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧