C++Prime 第14章 前30题
练习14.1
重载运算符与内置运算符:
区别:
1)某些运算对象的求值规则无法在重载运算符中保存下来.比如&&和||的短路求值特性被舍弃.
2)重载运算符必须要求至少有一个成员是class类型
相同:
1)一般来说,优先级,结合律和操作数的数目是一致的.
2)一般来说,表达的逻辑是相同的.
练习14.2
friend std::istream& operator>>(std::istream& is, Sales_data&);
friend std::ostream& operator<<(std::ostream& os, const Sales_data&);
friend Sales_data operator+(const Sales_data& s1,const Sales_data& s2);
Sales_data& operator+=(const Sales_data& s);
std::istream& operator>>(std::istream& is, Sales_data& tmp)
{
double price;
is >> tmp.bookNo >> tmp.units_sold >> price;
if (is)
tmp.revenue = tmp.units_sold * price;
else
tmp = Sales_data();
return is;
}
std::ostream& operator<<(std::ostream& os, const Sales_data& tmp)
{
os << tmp.bookNo << " " << tmp.units_sold << " " << tmp.revenue;
return os;
}
Sales_data operator+(const Sales_data& s1, const Sales_data& s2)
{
if (s1.bookNo == s2.bookNo)
{
Sales_data tmp;
tmp.bookNo = s1.bookNo;
tmp.units_sold = s1.units_sold + s2.units_sold;
tmp.revenue = s1.revenue + s2.revenue;
return tmp;
}
else
throw runtime_error("不可相加");
}
练习14.3
(a)内置版本,比较两个指针
(b)string版本,比较两个string
©vector版本
(d)string版本,const char*被转换
练习14.4
应该是类的成员的:
%= (改变对象状态),
++ (改变对象状态),
-> (与给定类型密切相关),
() (必须是)
其实都不应该是.
原因:
有4个必须是成员: =,[],(),->
复合赋值应该是.
改变对象状态的,或者与给定类型密切相关的运算符,如:++,–,* 应该是.
具有对称性的一般不是.
练习14.5
全部应该定义,最起码的<<,>>,==,!=,是很有必要定义的
部分例子:
friend std::ostream& operator<<(std::ostream& os,const Book& b);
friend std::istream& operator>>(std::istream& is,Book& b);
friend Book operator+(const Book& b1,const Book& b2);
练习14.6
见练习14.2
练习14.7
friend std::ostream& operator<<(std::ostream& os,const String& s);
练习14.8
上面有
练习14.9
上面有
练习14.10
(a) 正常读入
(b)生成默认的对象,流状态被值错误位
练习14.11
输入运算符必须处理输入可能失败的情况.
如果仍按上述练习输入,程序将会抛出异常.
练习14.12
std::istream& operator>>(std::istream& is, Date& date)
{
is >> date.m_year >> date.m_month >> date.m_day;
if (!is)
date = Date();
return is;
}
练习14.13
声明个减法:
friend Sales_data operator-(const Sales_data& s1, const Sales_data& s2);
练习14.14
可读性高,重用代码,方便更改.
练习14.15
应该.
练习14.16
friend bool operator==(const StrVec& s1, const StrVec& s2);
friend bool operator!= (const StrVec& s1, const StrVec& s2);
bool operator==(const StrVec& s1, const StrVec& s2)
{
if(s1.size() != s2.size()) return false;//长度不相等
for (auto p1 = s1.elements, p2 = s2.elements; p1 != s1.first_free; ++p1, ++p2)
if (*p1 != *p2)
return false;
return true;
}
bool operator!=(const StrVec& s1, const StrVec& s2)
{
return s1 == s2;
}
练习14.19
应该有,基本每个类都应该有.
friend bool operator==(const Person& p1, const Person& p2);
friend bool operator!=(const Person& p1, const Person& p2);
bool operator==(const Person& p1, const Person& p2)
{
return (p1.m_name == p2.m_name && p1.m_address == p2.m_address);
}
bool operator!=(const Person& p1, const Person& p2)
{
return p1 == p2;
}
练习14.20
Sales_data& Sales_data::operator+=(const Sales_data& s)
{
units_sold += s.units_sold;
revenue += s.revenue;
return *this;
}
Sales_data operator+(const Sales_data& s1, const Sales_data& s2)
{
Sales_data tmp = s1;
tmp += s2;
return tmp;
}
练习14.21
本题无任何性能提升,同时可读性差
练习14.22
Sales_data& Sales_data::operator=(const std::string no)
{
bookNo = no;
return* this;
}
练习14.23
StrVec& StrVec::operator=(initializer_list<string> il)
{
auto data = alloc_n_copy(il.begin(),il.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
练习14.24
Person::Person(const Person& p)
{
m_name = p.m_name;
m_address = p.m_address;
}
Person::Person(Person&& p)
{
m_name = std::move(p.m_name);
m_address = std::move(p.m_address);
m_name = m_address = "";
}
练习14.25
不用定义别的啦
练习14.26
string& operator[](size_t n) { return elements[n]; }
const string& operator[](size_t n)const { return elements[n]; }
练习14.27
StrBlobPtr& StrBlobPtr::operator++()
{
check(curr,"increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr& StrBlobPtr::operator--()
{
--curr;
check(curr,"decrement past begin of SreBlobPtr");
return *this;
}
StrBlobPtr StrBlobPtr::operator++(int)
{
StrBlobPtr ret = *this;
++*this;
return ret;
}
StrBlobPtr StrBlobPtr::operator--(int)
{
StrBlobPtr ret = *this;
--*this;
return ret;
}
练习14.28
StrBlobPtr StrBlobPtr::operator+(int n)
{
auto ret = *this;
ret.curr += n;
return ret;
}
StrBlobPtr StrBlobPtr::operator-(int n)
{
auto ret = *this;
ret.curr -= n;
return ret;
}
练习14.29
因为要改变对象的状态.
练习14.30
略