有个稍微特殊的容器成员,定义从输入到输出,到下标等的一系列操作符
PE14.7
//为下面的类顶一个一个输出操作符,
#include"head.h"
class CheckoutRecord{
public:
CheckoutRecord(std::vector< std::pair<std::string, std::string>* > wait_list): book_id(0.0), title("hell"), date_borrowed(1988), date_due(1999),
borrower(std::make_pair("hu", "qw")), wait_list(wait_list){}
CheckoutRecord(): book_id(0.0), title("hell"), date_borrowed(1988), date_due(1999),
borrower(std::make_pair("hu", "qw")){}
friend std::ostream&
operator<<(std::ostream&, const CheckoutRecord&);
typedef unsigned Date;
private:
double book_id;
std::string title;
//借书还书日期
Date date_borrowed;//Date是标准库的?先自定义一个
Date date_due;//
std::pair<std::string, std::string> borrower;//用pair存放单个借阅者的名字
std::vector< std::pair<std::string, std::string>* > wait_list;//vector存储(指向每个排队者)的指针
};
std::ostream&
operator<<(std::ostream& out, const CheckoutRecord& check){
out << check.book_id << "\t" << check.title
<< "\t" << check.date_borrowed << "\t" << check.date_due
<< "\t" << check.borrower.first << "\t" << check.borrower.second;
for(std::vector< std::pair<std::string, std::string> *>::const_iterator iter = check.wait_list.begin();
iter != check.wait_list.end(); iter++){//循环输出排队列表
out << std::endl << "第" << (iter - check.wait_list.begin()) + 1 << "排队者: " <<(*iter)->first << "\t" << (*iter)->second;
}
return out;
}
int main(){
//声明定义一个排队列表
std::vector< std::pair<std::string, std::string>* > wait_list;
std::string first_name = "holy";
std::string second_name = "god";
std::pair<std::string, std::string> name2 = std::make_pair("zhang", "lixin");
wait_list.push_back(&name2);//其他三个有warning,因为是make_pair临时变量
wait_list.push_back(&std::make_pair(first_name, second_name));
wait_list.push_back(&std::make_pair(first_name, first_name));
wait_list.push_back(&std::make_pair(second_name, first_name));//为什么这个输出不按格式走呢,与位置无关,放那都一样
CheckoutRecord check1(wait_list);
std::cout << check1 << std::endl;
}
pe14_11
//输入操作符,要求对错误处理,最后一个成员肯定不是能in的
std::istream&
operator>>(std::istream& in, CheckoutRecord& check){
in >> check.book_id >> check.title
>> check.date_borrowed >> check.date_due
>> check.borrower.first>>check.borrower.second;
if(!in)
check = CheckoutRecord();
return in;
}
pe14_17
//定义下标操作符,下标操作符要考虑返回的是个左值,被赋值的情况,check1[1]->first = "asd";所以需要一个非const
std::pair<std::string, std::string>*
CheckoutRecord::operator[](const size_t index){
return wait_list[index];
}
const std::pair<std::string, std::string>*
CheckoutRecord::operator[](const size_t index) const{//返回的都是指针,无所谓const了,反正都能改队列内容pair
return wait_list[index];
}
int main(){
std::cout << check1[1]->first << "\t" << check1[1]->second << std::endl;
}
pe14_18//优点,操作方便,缺点,类有很多成员,而下标只是排队列表的pair的指针,怕是不通俗,不好理解
另一人为缺点是不进行下标越界检查,实际上用wait_list.size()对比一下就型了把
要不getQueueMemberFirst、getQueueMemberSecond(),
要么就在实现里自己取出来字符串拼接起来,返回字符串:
std::string
CheckoutRecord::getQueueMember(const size_t index){
return wait_list[index]->first + "\t" + wait_list[index]->second;
}
不过这是封装过得了,不能当左值被改变了
必须有const版本,不然getQueueMember(1) = "asd";还能执行,不过没有任何效果,误导
const std::string&
CheckoutRecord::getQueueMember const(const size_t index) const{//这个也不对,返回的是对临时string的引用,因为是重载(const引起的重载),也不阻止给返回值的赋值操作
return wait_list[index]->first + "\t" + wait_list[index]->second;
}
const std::string
CheckoutRecord::getQueueMember(const size_t index) const{//只定义一个它就对了,不要重载,这属于封装了,不是下标操作符了,就需要无法改变
return wait_list[index]->first + "\t" + wait_list[index]->second;
}
pe14_19.cpp:86:29: error: passing ‘const std::string’ as ‘this’ argument of
‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*)
[with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>,
std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]’ discards qualifiers