14.1节
练习14.1
相同点:对于优先级和结合型以及操作数的数目都不变。
不同点:重载操作符必须具有至少一个class或枚举类型的操作数。
14.2
//sales_data.h #ifndef SALES_DATA_H #define SALES_DATA_H #include#include using namespace std; class Sales_data { friend void print(ostream &os,Sales_data rhs); friend istream& operator>>(istream &,Sales_data &rhs); friend ostream& operator<<(ostream &,const Sales_data &rhs); public: Sales_data() = default; Sales_data(const string &s):bookno(s){} Sales_data(const string &s,unsigned n,double r): bookno(s),cnt(n),revenue(r){} Sales_data(istream &is); const string & isbn()const {return bookno;} Sales_data operator+(const Sales_data &rhs); Sales_data &operator+=(const Sales_data &rhs); private: unsigned cnt = 0; double revenue = 0.0; string bookno; }; void print(ostream &os,Sales_data rhs); istream& operator>>(istream &,const Sales_data &rhs); ostream& operator<<(ostream &,const Sales_data &rhs); #endif //functions.cc #include #include #include "sales_data.h" using namespace std; Sales_data & Sales_data::operator+=(const Sales_data &rhs) { if(this->bookno != rhs.bookno) throw runtime_error("Not same type."); this->revenue += rhs.revenue; this->cnt += rhs.cnt; return *this; } Sales_data Sales_data::operator+(const Sales_data &rhs) { if(this->bookno != rhs.bookno) throw runtime_error("Not the same type."); Sales_data data; data.bookno = rhs.bookno; data.revenue = this->revenue + rhs.revenue; data.cnt = this->cnt + rhs.cnt; return data; } void print(ostream &os,Sales_data rhs) { os <<"bookno:"< >(istream &is,Sales_data &rhs) { is >> rhs.bookno >> rhs.cnt >> rhs.revenue; return is; } ostream& operator<<(ostream &os,const Sales_data &rhs) { os << rhs.bookno << rhs.cnt << rhs.revenue; return os; } //main.cc #include #include #include "sales_data.h" using namespace std; int main() { Sales_data s1("book1",12,120); Sales_data s2("book1",12,130); s1 += s2; Sales_data s3 = s1 + s2; print(cout,s1); print(cout,s3); cout << "输入s1:" << endl; cin >> s1; cout << s1 << endl; return 0; }
bookno:book1 revenue:250 cnt:24 bookno:book1 revenue:380 cnt:36 输入s1: isbnabcdefg 12 120 isbnabcdefg12120
14.2
(a) 应用了c++内置版本的==,比较两个指针。
(b)应用了svec1[1] == svec2[0] 应用了string版本的重载==。
(c)应用了svec1 == svec2 应用了vector版本的重载==。
(d)svec1[0] == "stone"应用了 string版本的重载==,字符串字面知被转换为string。
14.3
答:
(a)%通常定义飞成员
(b)%=通常定义为成员,因为会改变对象的状态
(c)++通常定义为类成员,因为它会改变对象的状态。
(d)->必须定义为成员否则,否则编译器会报错。
(e)<<通常定义非成员。因为做操作数为输出流,如果定义成成员,那就不符合<<的本来内置习惯。
(f)&&通常是定义成非成员
(g)==通常定义为非成员(操作符具有对称性一般定义为非成员,这样才可以必要时候转换,成员不能转换,左边操作数是确定的)
(h)()必须定义为成员,否则编译器会报错。
总结:
赋值=、下标[]、成员->、成员()这四个是必须定义成成员函数的。
复合的运算符一般定义成成员,但是不是必须。
改变对象状态的运算符(++,--)或者和对象有密切关系的运算符应该定义成成员函数,例如递增递减和解引用。
具有对称运算的运算符可能转换任意一端的运算对象,例如算数、关系、相等性和位运算符要定义成非成员运算符。
14.7
类内声明
friend ostream & operator<<(ostream & ,const String &rhs);
类外声明:
ostream & operator<<(ostream & ,const String &rhs);
最后源文件中定义:
ostream & operator<<(ostream &os,const String &rhs)
{
for(auto p = rhs.elements; p != rhs.first_free; ++p)
{
os << *p;
}
return os;
}
补充和理解:
这里定义==和!=一定注意,如果类中有唯一一个动态内存,比如说strblobptr,当wptr都非空时候才比较curr,如果wptr都空时不必比较curr。也就是含有动态内存的类,比较的时候可能变量要分级对待(分级是我自己发明的说话,也就是说当内存都是nullptr时候,不必比较其它变量,也就是变量中间有级别的有限性,某些情况下,某个或者某些变量不必参与比较)。
14.2.2
14.3
14.3.1练习答案,这个答案产生一个疑问?两个StrBlob相等,到底是应该是data内的内容相等?还是data应该指向同一个vector?答案是比较了StrBlob的data的
bool operator==(const StrBlob & lhs,const StrBlob &rhs)
{
return (*(lhs.data) == *(rhs.data));
}
14.3.2节练习
14.18
friend声明和函数原型声明就略去了。看下面的定义:
//strblob.h中的
bool operator==(const StrBlob &lhs,const StrBlob & rhs)
{
return lhs.data == rhs.data;
}
bool operator<(const StrBlob &lhs,const StrBlob &rhs)
{
return *(lhs.data) < *(rhs.data);
}
bool operator>(const StrBlob &lhs,const StrBlob &rhs)
{
return *(lhs.data) > *(rhs.data);
}
bool operator<=(const StrBlob &lhs,const StrBlob &rhs)
{
return *(lhs.data) <= *(rhs.data);
}
bool operator>=(const StrBlob &lhs,const StrBlob &rhs)
{
return *(lhs.data) >=*(rhs.data);
}
说明:就是比较两个strblob对象是否指向同一个data,如果是则正确,如果否,那么不想等。
strblobptr类:
bool operator== (const StrBlobPtr &lhs,const StrBlobPtr &rhs)
{
if(lhs.wptr.lock() == rhs.wptr.lock())
{
//用auto l = lhs.wptr.lock() r = rhs.wptr.lock(),然后比较看起来更舒服
return !lhs.wptr.lock() || lhs.curr == rhs.curr;
}
else
{
return false;
}
}
bool operator!= (const StrBlobPtr &lhs,const StrBlobPtr &rhs)
{
return !(lhs == rhs);
}
bool operator> (const StrBlobPtr&,const StrBlobPtr&)
{
}
bool operator< (const StrBlobPtr&,const StrBlobPtr&)
{
}
bool operator>= (const StrBlobPtr&,const StrBlobPtr&)
{
}
bool operator<= (const StrBlobPtr&,const StrBlobPtr&)
{
}
这里含有动态内存,动态内存wptr和变量,如果在动态内存wptr为空的时候(两个动态内存相等的情况下),比较curr的大小是无意义的。所以这里wptr和curr不是同一个级别的变量。作用的大小也是不对等的。
string.h
bool operator==(const String &lhs,const String &rhs)
{
if(lhs.size() != rhs.size())
return false;
for(auto ptr1 = lhs.begin(),ptr2 = rhs.begin();
ptr1 != lhs.end() && ptr2 != rhs.end(); ++ ptr1,++ptr2)
{
if(*ptr1 != *ptr2)
return false;
}
return true;
}
bool operator!=(const String &lhs,const String &rhs)
{
return !(lhs == rhs);
}



