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
略