欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

C++Primer学习笔记第十四章重载运算与类型转换

时间:2023-05-27
C++ Primer 学习笔记 第十四章 重载运算与类型转换 494 重载sales_data的输出运算符

#include #include using namespace std;class Sales_data { friend ostream &operator<<(ostream &, const Sales_data &item);public: Sales_data(const std::string &s, unsigned n, double p):bookNo(s), units_sold(n), revenue(n*p){ } Sales_data() : Sales_data("", 0, 0.0f){ } std::string isbn() const { return bookNo; }private: inline double avg_price() const; std::string bookNo; unsigned units_sold = 0; double revenue = 0.0;};inline double Sales_data::avg_price() const{ return units_sold ? revenue/units_sold : 0;}ostream &operator<<(ostream &os, const Sales_data &item){ os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price(); return os;}int main(){ Sales_data data("abc", 2, 4); cout << data << endl;// abc 2 8 4 return 0;}

成员函数版本的重载<< 不推荐

#include #include using namespace std;class Sales_data {public: Sales_data(const std::string &s, unsigned n, double p):bookNo(s), units_sold(n), revenue(n*p){ } Sales_data() : Sales_data("", 0, 0.0f){ } std::string isbn() const { return bookNo; } ostream &operator<<(ostream&);private: inline double avg_price() const; std::string bookNo; unsigned units_sold = 0; double revenue = 0.0;};inline double Sales_data::avg_price() const{ return units_sold ? revenue/units_sold : 0;}ostream & Sales_data::operator<<(ostream &os) { os << this->isbn() << " " << this->units_sold << " " << this->revenue << " " << this->avg_price(); return os;}int main(){ Sales_data data("abc", 2, 4); data << cout; // abc 2 8 4 return 0;}

495 重载输入运算符

#include #include using namespace std;class Sales_data { friend ostream &operator<<(ostream &, Sales_data&); friend istream &operator>>(istream &, Sales_data &);public: Sales_data(const std::string &s, unsigned n, double p):bookNo(s), units_sold(n), revenue(n*p){ } Sales_data() : Sales_data("", 0, 0.0f){ } std::string isbn() const { return bookNo; }private: inline double avg_price() const; std::string bookNo; unsigned units_sold = 0; double revenue = 0.0;};inline double Sales_data::avg_price() const{ return units_sold ? revenue/units_sold : 0;}ostream &operator<<(ostream &os, Sales_data& data){ os << data.bookNo << " " << data.units_sold << " " << data.revenue << " " << data.avg_price(); return os;}istream &operator>>(istream &is, Sales_data &item){ double price; is >> item.bookNo >> item.units_sold >> price; if (is) item.revenue = item.units_sold*price; else item = Sales_data(); return is;}int main(){ Sales_data data("abc", 2, 4); cout << data << endl; // abc 2 8 4 cout << "please enter bookNo, units_sold, price: " << endl; cin >> data; cout << data; return 0;}

497 重写+=和+

Sales_data& Sales_data::operator+=(const Sales_data &rhs) { units_sold += rhs.units_sold; revenue += rhs.revenue; return *this;}Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs){ Sales_data sum = lhs; sum += rhs; return sum;}

499 运算符重写综合实例

#include #include using namespace std;class Sales_data { friend ostream &operator<<(ostream &, Sales_data&); friend istream &operator>>(istream &, Sales_data &); friend bool operator==(const Sales_data&, const Sales_data&); friend bool operator!=(const Sales_data&, const Sales_data&);public: Sales_data(const std::string &s, unsigned n, double p):bookNo(s), units_sold(n), revenue(n*p){ } Sales_data() : Sales_data("", 0, 0.0f){ } std::string isbn() const { return bookNo; } Sales_data& operator+=(const Sales_data &rhs);private: inline double avg_price() const; std::string bookNo; unsigned units_sold = 0; double revenue = 0.0;};inline double Sales_data::avg_price() const{ return units_sold ? revenue/units_sold : 0;}ostream &operator<<(ostream &os, Sales_data& data){ os << data.bookNo << " " << data.units_sold << " " << data.revenue << " " << data.avg_price(); return os;}istream &operator>>(istream &is, Sales_data &item){ double price; is >> item.bookNo >> item.units_sold >> price; item.revenue = item.units_sold*price; return is;}Sales_data& Sales_data::operator+=(const Sales_data &rhs) { units_sold += rhs.units_sold; revenue += rhs.revenue; return *this;}Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs){ Sales_data sum = lhs; sum += rhs; return sum;}bool operator==(const Sales_data& lhs, const Sales_data& rhs){ return lhs.isbn()==rhs.isbn() && lhs.units_sold==rhs.units_sold && lhs.revenue==rhs.revenue;}bool operator!=(const Sales_data &lhs, const Sales_data &rhs){ return !(lhs==rhs);}int main(){ Sales_data data("abc", 2, 4); cout << data << endl; // abc 2 8 4// cout << "please enter bookNo, units_sold, price: " << endl;// cin >> data;// cout << data; Sales_data data2("efg", 3, 5); Sales_data data3 = data + data2; cout << data3; return 0;}

501 下标运算符

string& operator[](size_t n){return elements[n];}; const string& operator[](size_t n) const{return elements[n];};

503 前置和后置版本的++

#include #include #include #include #include #include #include using namespace std;class StrBlob{public: friend class StrBlobPtr; StrBlobPtr begin(); StrBlobPtr end(); typedef std::vector::size_type size_type; StrBlob(); StrBlob(std::initializer_list il); size_type size() const {return data->size();}; bool empty() const {return data->empty();}; void push_back(const std::string &t){data->push_back(t);}; void pop_back(); std::string& front(); std::string& back(); std::shared_ptr> data;private: void check(size_type i, const std::string &msg) const;};StrBlob::StrBlob() :data(make_shared>()){}StrBlob::StrBlob(initializer_list il):data(make_shared>(il)){}void StrBlob::check(size_type i, const std::string &msg) const { if (i>=data->size()) throw out_of_range(msg);}string& StrBlob::front() { check(0, "front on empty StrBlob"); return data->front();}string& StrBlob::back() { check(0, "back on empty StrBlob"); return data->back();}void StrBlob::pop_back() { check(0, "pop_back on empty StrBlob"); data->pop_back();}class StrBlobPtr{public: StrBlobPtr():curr(0){} StrBlobPtr(StrBlob &a, size_t sz=0):wptr(a.data), curr(sz){} string& deref() const; StrBlobPtr& incr(); // front ++ StrBlobPtr operator++(); // back ++ StrBlobPtr operator++(int);private: shared_ptr> check(size_t, const string&) const; weak_ptr> wptr; size_t curr;};//shared_ptr>;shared_ptr> StrBlobPtr::check(size_t i, const string &msg) const { auto ret = wptr.lock(); if (!ret){ throw runtime_error("unbound StrBlobPtr"); } if (i>=ret->size()) throw out_of_range(msg); return ret;}string& StrBlobPtr::deref() const { auto p = check(curr, "dereference past end"); return (*p)[curr];}StrBlobPtr& StrBlobPtr::incr() { check(curr, "increment past end of StrBlobPtr"); ++curr; return *this;}StrBlobPtr StrBlob::begin(){ return StrBlobPtr(*this);}StrBlobPtr StrBlob::end(){ return StrBlobPtr(*this, data->size());}StrBlobPtr StrBlobPtr::operator++() { check(curr, "increment past end ofStrBlobPtr"); ++curr; return *this;}StrBlobPtr StrBlobPtr::operator++(int) { StrBlobPtr ret = *this; ++*this; return ret;}int main() { StrBlob stb; StrBlobPtr stbr(stb); vector vec = {"a", "b", "c"}; for (string text:vec){ stb.push_back(text); } auto begin = stb.begin(); auto end = stb.end(); stbr++; ++stbr; while(true){ try{ cout <

504 重写解引用运算符

#include #include #include #include #include #include #include using namespace std;class StrBlob{public: friend class StrBlobPtr; StrBlobPtr begin(); StrBlobPtr end(); typedef std::vector::size_type size_type; StrBlob(); StrBlob(std::initializer_list il); size_type size() const {return data->size();}; bool empty() const {return data->empty();}; void push_back(const std::string &t){data->push_back(t);}; void pop_back(); std::string& front(); std::string& back(); std::shared_ptr> data;private: void check(size_type i, const std::string &msg) const;};StrBlob::StrBlob() :data(make_shared>()){}StrBlob::StrBlob(initializer_list il):data(make_shared>(il)){}void StrBlob::check(size_type i, const std::string &msg) const { if (i>=data->size()) throw out_of_range(msg);}string& StrBlob::front() { check(0, "front on empty StrBlob"); return data->front();}string& StrBlob::back() { check(0, "back on empty StrBlob"); return data->back();}void StrBlob::pop_back() { check(0, "pop_back on empty StrBlob"); data->pop_back();}class StrBlobPtr{public: StrBlobPtr():curr(0){} StrBlobPtr(StrBlob &a, size_t sz=0):wptr(a.data), curr(sz){} string& deref() const; StrBlobPtr& incr(); // front ++ StrBlobPtr operator++(); // back ++ StrBlobPtr operator++(int); StrBlobPtr operator--(); string& operator*() const{ auto p = check(curr, "dereference past end"); cout << "curr: " << curr << endl; return (*p)[curr]; }private: shared_ptr> check(size_t, const string&) const; weak_ptr> wptr; size_t curr;};//shared_ptr>;shared_ptr> StrBlobPtr::check(size_t i, const string &msg) const { auto ret = wptr.lock(); if (!ret){ throw runtime_error("unbound StrBlobPtr"); } if (i>=ret->size()) throw out_of_range(msg); return ret;}string& StrBlobPtr::deref() const { auto p = check(curr, "dereference past end"); return (*p)[curr];}StrBlobPtr& StrBlobPtr::incr() { check(curr, "increment past end of StrBlobPtr"); ++curr; return *this;}StrBlobPtr StrBlob::begin(){ return StrBlobPtr(*this);}StrBlobPtr StrBlob::end(){ return StrBlobPtr(*this, data->size());}StrBlobPtr StrBlobPtr::operator++() { check(curr, "increment past end ofStrBlobPtr"); ++curr; return *this;}StrBlobPtr StrBlobPtr::operator++(int) { StrBlobPtr ret = *this; ++*this; return ret;}StrBlobPtr StrBlobPtr::operator--() { check(curr, "increment past end ofStrBlobPtr"); --curr; return *this;}int main() { StrBlob a1 = {"hi", "bye", "now"}; StrBlobPtr p(a1); *p = "okay"; cout << *p << endl; // okay cout << *(++p) << endl; // bye return 0;}

506 重写调用运算符

#include #include #include #include #include #include #include using namespace std;struct absInt{ int operator() (int val) const { return val < 0 ? -val:val; }};int main() { int i = -42; absInt absObj; cout << absObj(i) << endl; return 0;}

507 重载运算符和for_each结合使用

#include #include #include #include #include #include #include #include using namespace std;class PrintString{public: PrintString(ostream &o=cout, char c=' '):os(o),sep(c){} void operator()(const string &s) const{os << s << sep;}private: ostream &os; char sep;};int main() { PrintString printer; string s = "hello world"; printer(s); // hello world cout << endl; PrintString errors(cerr, 'n'); errors(s); // hellowordn cout << endl; vector vs = {"a", "b", "c"}; for_each(vs.begin(), vs.end(), errors); return 0;}

508 类对象和lambda函数的互换

#include #include #include #include #include #include #include #include using namespace std;class ShorterString{public: bool operator()(const string &s1, const string &s2) const { return s1.size() < s2.size(); }};bool compare(const string &s1, const string &s2){ return s1.size() < s2.size();}int main() { vector words = {"a", "abcd", "ab", "abc"};// stable_sort(words.begin(), words.end(),// [](const string &a, const string &b){return a.size() out_iter(cout, " "); copy(words.begin(), words.end(), out_iter); return 0;}

508 类对象代替lambda捕获参数

#include #include #include #include #include #include #include #include using namespace std;void elimDups(vector &words){ sort(words.begin(), words.end()); auto unqi = unique(words.begin(), words.end()); words.erase(unqi, words.end());}class SizeComp{public: SizeComp(size_t n):sz(n){} bool operator()(const string &s) const{ return s.size() >= sz; }private: size_t sz;};void biggies(vector &words, vector::size_type sz){ elimDups(words); stable_sort(words.begin(), words.end(), [](const string &a, const string &b){return a.size()=sz;}); auto wc = find_if(words.begin(), words.end(), SizeComp(sz)); auto count = words.end() - wc; cout << count << endl; // 5 5 elements with length >=4 for_each(wc, words.end(),[](const string &s){cout << s << " ";}); cout << endl; // over slow jumps quick turtle}int main() { vector vec= {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"}; biggies(vec, 4);}

510 使用标准库函数对象

#include #include #include #include #include #include #include #include #include using namespace std;bool compare(const int *a, const int *b){ return *a < *b;}int main() { plus intAdd; negateintNegate; int sum = intAdd(10, 20); cout << sum << endl; // 30 sum = intNegate(intAdd(10, 20)); cout << sum << endl; // -30 vector nums = {1, 3, 2, 6, 5, 4}; vector p_nums; for (auto iter=nums.begin(); iter!=nums.end(); ++iter){ p_nums.push_back(&*iter); }// sort(p_nums.begin(), p_nums.end(), [](string *a, string *b){return (*a)<(*b);});// sort(p_nums.begin(), p_nums.end(), less()); sort(p_nums.begin(), p_nums.end(), compare); for (auto iter=p_nums.begin(); iter!=p_nums.end(); ++iter){ cout << **iter << " "; } cout << endl; // 1 2 3 4 5 6}

512 可调用对象与function

#include #include #include #include #include #include #include #include #include #include using namespace std;int add(int a, int b){ return a+b;}class divide{public: int operator()(int a, int b){return a/b;};};int main() { function f1 = add; function f2 = divide(); function f3 = [](int i, int j){return i*j;}; cout << f1(4, 2) << endl; //6 cout << f2(4, 2) << endl; //2 cout << f3(4, 2) << endl; //8 }

513 function结合map构造计算器

#include #include #include #include #include #include #include #include #include #include using namespace std;int add(int a, int b){ return a+b;}class divide{public: int operator()(int a, int b){return a/b;};};auto mod = [](int i, int j){return i%j;};int main() { map> binops ={ {"+", add}, {"-", minus()}, {"/", divide()}, {"*", [](int i, int j){return i*j;}}, }; cout<< binops["+"](10, 5) << endl; }

514 类型转换运算符

#include #include #include #include #include #include #include #include #include #include using namespace std;class SmallInt{public: SmallInt(int i=0, int j=0):val(i){ if(i<0||i>255){ throw out_of_range("Bad SmallInt value"); } } operator int() const{return val;}; size_t val;};int main() { SmallInt si; si = 4; cout << si.val << endl; // 4 cout << si+3 << endl; // 7 si = 3.14; cout << si.val << endl; // 3 cout << si+3.14 << endl; // 6.14}

516 类类型显式转换运算符

#include #include #include #include #include #include #include #include #include #include using namespace std;class SmallInt{ friend ostream& operator<<(ostream &, const SmallInt &);public: SmallInt(int n=0):val(n){} explicit operator int() const{ return val; }private: size_t val;};ostream& operator<<(ostream &os, const SmallInt &item){ os << item.val; return os;}int main() { SmallInt si; si = 4; cout << si << endl; // error// si + 3; // ok because of explicit conversion cout << static_cast(si) + 3 << endl; //7}

14.47 类方法两个不同的const的区别

#include #include #include #include #include #include #include #include #include #include using namespace std;struct Integral{ Integral(int n=0):val(n){ } operator const int(){ cout << "operator const int()" << endl; val = 6; return val; }; operator int() const{ cout << "operator int() const" << endl;// val = 6 return 4; }; int val;};int main() { Integral itg; const Integral itg2; itg = 3; //constructor int i = itg; // operator const int() int j = itg2; // operator int() const}

520 避免二义性

#include #include #include #include #include #include #include #include #include #include using namespace std;struct C{ C(int){};};struct D{ D(int){};};void manip(const C&){}void manip(const D&){}int main() { // ambiguous manip(10); manip(C(10));}

14.51

#include #include #include #include #include #include #include #include #include #include using namespace std;struct LongDouble{ LongDouble(double = 0.0){cout << "constructor" << endl;}; operator double(){return 2;}; operator float(){return 4;};};void calc(int){};void calc(LongDouble){};int main() { LongDouble ldObj; float ex2 = ldObj; //double double dval=5; calc(dval); // constructor}

522 算术类型转换和重载运算符的二义性

#include #include #include #include #include #include #include #include #include #include using namespace std;class SmallInt{ friend SmallInt operator+(const SmallInt&, const SmallInt&);public: SmallInt(int n =0):val(n){}; operator int() const{return val;} size_t val;};SmallInt operator+(const SmallInt& a, const SmallInt& b){ SmallInt res; res.val = a.val + b.val; return res;}int main() { SmallInt s1(1), s2(2); SmallInt s3 = s1 + s2; cout << s3.val << endl; // ambiguous// int i = s3 + 0;}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。