C++Prime 第14章 前30题

    技术2025-05-14  54

    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

    Processed: 0.012, SQL: 9