Contents
Homework
Test 14.2
class my_sales_data
{
friend std::istream& operator>>(std::istream&, my_sales_data&);
friend std::ostream& operator<<(std::ostream&, const my_sales_data&);
friend my_sales_data operator+(const my_sales_data&, const my_sales_data&);
public:
//构造函数(声明)
//my_sales_data() : units_sold(0), revenue(0.0) {}; //使用类内初始值
my_sales_data(std::string s) : bookNo(s) {};
my_sales_data(std::string s, unsigned n, double r) : bookNo(s), units_sold(n), revenue(r) { std::cout << 'a' << std::endl; };
my_sales_data() : my_sales_data("1001", 0, 0) { std::cout << 'b' << std::endl; }; //使用委托构造函数
my_sales_data(std::istream&);
inline double avg_price() const;
std::string isbn() const { return bookNo; }
my_sales_data& operator+=(const my_sales_data&);
private:
//成员变量
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
//非成员接口函数(声明)
my_sales_data operator+(const my_sales_data&, const my_sales_data&);
std::ostream& operator<<(std::ostream&, const my_sales_data&);
std::istream& operator>>(std::istream&, my_sales_data&);
//===== 构造函数 =====
my_sales_data::my_sales_data(std::istream& is)
{
is >> *this;
}
//===== 成员函数 =====
inline double my_sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
my_sales_data& my_sales_data::operator+=(const my_sales_data& rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
//===== 非成员接口函数 ======
std::istream& operator>>(std::istream& is, my_sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = item.units_sold * price;
return is;
}
std::ostream& operator<<(std::ostream& os, const my_sales_data & item)
{
os << item.bookNo << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
my_sales_data operator+(const my_sales_data& lhs, const my_sales_data& rhs)
{
my_sales_data sum = lhs;
sum += rhs;
return sum;
}
Test 14.16
strblob
bool operator==(const strblob& lhs, const strblob& rhs)
{
return lhs.data == rhs.data;
}
bool operator!=(const strblob& lhs, const strblob& rhs)
{
return !(lhs == rhs);
}
StrBlobPtr
bool operator==(const strblobptr& lhs, const strblobptr& rhs) {
auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
// 若底层的 vector 是同一个
if (l == r)
// 则两个指针都是空,或者指向相同元素时,它们相等
return (!r || lhs.curr == rhs.curr);
else
return false; // 若指向不同 vector,则不可能相等
}
bool operator!=(const strblobptr& lhs, const strblobptr& rhs) {
return !(lhs == rhs);
}
StrVec
bool operator==(const StrVec& lhs, const StrVec& rhs)
{
if (lhs.size() != rhs.size() || lhs.capacity() != rhs.capacity())
return false;
for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
{
if (*it1 != *it2)
return false;
}
return true;
}
bool operator!=(const StrVec& lhs, const StrVec& rhs)
{
return !(lhs == rhs);
}
String
bool operator==(const String& lhs, const String& rhs)
{
if (lhs.size() != rhs.size() || lhs.capacity() != rhs.capacity())
return false;
for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
{
if (*it1 != *it2)
return false;
}
return true;
}
bool operator!=(const String& lhs, const String& rhs)
{
return !(lhs == rhs);
}
Test 14.18
strblob
bool operator<(const strblob& lhs, const strblob& rhs)
{
return *lhs.data < *rhs.data;
}
bool operator>(const strblob& lhs, const strblob& rhs)
{
return rhs < lhs;
}
bool operator<=(const strblob& lhs, const strblob& rhs)
{
return !(lhs > rhs);
}
bool operator>=(const strblob& lhs, const strblob& rhs)
{
return !(lhs < rhs);
}
StrBlobPtr
bool operator<(const strblobptr& lhs, const strblobptr& rhs) {
auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
if (l == r)// 若底层的 vector 是同一个
{
if (!r)
return false; //如果两个指针都是空,无法比较
return lhs.curr < rhs.curr;//lhs指向的元素在rhs指向的元素前面时返回true
}
else
return false; // 若指向不同 vector,则无法比较
}
bool operator>(const strblobptr& lhs, const strblobptr& rhs)
{
return rhs < lhs;
}
bool operator<=(const strblobptr& lhs, const strblobptr& rhs)
{
return !(lhs > rhs);
}
bool operator>=(const strblobptr& lhs, const strblobptr& rhs) {
return !(lhs < rhs);
}
StrVec
bool operator<(const StrVec& lhs, const StrVec& rhs)
{
if (lhs.size() < rhs.size())
return true;
else if (lhs.size() == rhs.size())
{
for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
{
if (*it1 >= *it2)
return false;
}
}
else
return false;
return true;
}
bool operator>(const StrVec& lhs, const StrVec& rhs)
{
return rhs < lhs;
}
bool operator<=(const StrVec& lhs, const StrVec& rhs)
{
return !(lhs > rhs);
}
bool operator>=(const StrVec& lhs, const StrVec& rhs)
{
return !(lhs < rhs);
}
String
bool operator<(const String& lhs, const String& rhs)
{
if (lhs.size() < rhs.size())
return true;
else if (lhs.size() == rhs.size())
{
for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
{
if (*it1 >= *it2)
return false;
}
}
else
return false;
return true;
}
bool operator>(const String& lhs, const String& rhs)
{
return rhs < lhs;
}
bool operator<=(const String& lhs, const String& rhs)
{
return !(lhs > rhs);
}
bool operator>=(const String& lhs, const String& rhs)
{
return !(lhs < rhs);
}
Test 14.22
my_sales_data& my_sales_data::operator=(const std::string& isbn)
{
bookNo = isbn;
return *this;
}
Test 14.23
StrVec& StrVec::operator=(initializer_list<string> il)
{
//alloc_n_copy分配新内存空间并拷贝元素
auto data = alloc_n_copy(il.begin(), il.end());
free();
//更新指针
elements = data.first;
first_free = cap = data.second;
return *this;
}
Test 14.26
StrVec
class StrVec
{
string& operator[](size_t n) { return *(elements +n); };
const string& operator[](size_t n) const { return *(elements + n); };
}
String
class String
{
char& operator[](size_t n) { return *(elements + n); };
const char& operator[](size_t n) const { return *(elements + n); };
}
strblob
class strblob
{
string& operator[](size_t n) { check(n, "out of range"); return (*data)[n]; }
const string& operator[](size_t n) const { check(n, "out of range"); return (*data)[n]; }
}
strblobptr
class strblobptr
{
string& operator[](size_t n) { auto p = check(n, "out of range"); return (*p)[n]; }
const string& operator[](size_t n) const { auto p = check(n, "out of range"); return (*p)[n]; }
}
Test 14.27-14.28
strblobptr.h
class strblobptr
{
friend strblobptr operator+(strblobptr&, size_t n);
friend strblobptr operator-(strblobptr&, size_t n);
public:
strblobptr& operator++();
strblobptr& operator--();
strblobptr operator++(int);
strblobptr operator--(int);
strblobptr& operator+=(size_t n);
strblobptr& operator-=(size_t n);
private:
shared_ptr<vector<string>> check(size_t, const string&) const;
weak_ptr<vector<string>> wptr;
size_t curr;
};
strblobptr.cpp
strblobptr& strblobptr::operator++()
{
check(curr, "increment past end of strblobptr"); //如果已经指向了尾后位置,则无法递增
++curr;
return *this;
}
strblobptr& strblobptr::operator--()
{
--curr;
check(curr, "decrement past begin of strblob");
return *this;
}
strblobptr strblobptr::operator++(int)
{
strblobptr ret = *this;
++(*this);
return ret;
}
strblobptr strblobptr::operator--(int)
{
strblobptr ret = *this;
--(*this);
return ret;
}
strblobptr& strblobptr::operator+=(size_t n)
{
check(curr + n, "increment past end of strblobptr");
curr += n;
return *this;
}
strblobptr& strblobptr::operator-=(size_t n)
{
curr -= n;
check(curr, "decrement past begin of strblob");
return *this;
}
strblobptr operator+(strblobptr& lhs, size_t n)
{
return lhs += n;
}
strblobptr operator-(strblobptr& lhs, size_t n)
{
return lhs -= n;
}
Test 14.32
class ToPtr {
public:
ToPtr() = default;
ToPtr(strblobptr* p) : pointer(p) {}
strblobptr& operator*() { return *this->pointer; };
strblobptr* operator->() { return &this->operator*(); };
private:
strblobptr* pointer = nullptr;
};
int main() {
strblob a1 = { "hi", "bye", "now" };
strblobptr p1(a1); // p1 指向 a1 中的 vector
ToPtr p(&p1);
cout << p->operator->()->front();
cout << p->operator->()->back() << endl;
return 0;
}
Test 14.34
class ifelse
{
public:
ifelse() = default;
int operator()(bool state, int b, int c) {
if (state)
return b;
else
return c;
}
};
Test 14.35
class printstr
{
public:
printstr(istream& i = cin, ostream& o = cout) :is(i), os(o) {};
string operator()() { return (getline(is, str) ? str : " "); };
private:
istream& is;
ostream& os;
string str;
};
int main()
{
ifstream fin("infile.txt");
printstr obj(fin);
cout << obj();
return 0;
}
Test 14.36
int main()
{
ifstream fin("infile.txt");
printstr obj(fin);
vector<string> svec;
string s = obj();
while (s != " ")
{
svec.push_back(s);
s = obj();
}
for (auto& s : svec)
cout << s << endl;
return 0;
}
Test 14.37
class checkequal
{
public:
checkequal(const char& l) :a(l) {};
bool operator()(const char& b) { return a == b; }
private:
char a;
};
int main()
{
string str("abcdabcdabcd");
for (auto& c : str)
{
checkequal obj('c');
replace_if(str.begin(), str.end(), obj, 'C');
}
for (auto& c : str)
cout << c;
cout << endl;
return 0;
}
Test 14.38
class checksize
{
public:
checksize(const string& s) : str(s) {};
int operator()() { return str.size(); };
private:
string str;
};
int main()
{
ifstream fin("infile.txt");
string s;
map<int, int> counts;
while (fin >> s)
{
checksize size(s);
++counts[size()];
}
for (auto& p : counts)
cout << p.first << " occurs: " << p.second << endl;
return 0;
}
Test 14.39
int main()
{
ifstream fin("infile.txt");
string s;
map<int, int> counts;
int short_word = 0;
int long_word = 0;
while (fin >> s)
{
checksize size(s);
size() > 9 ? ++long_word : ++short_word;
}
cout << "short word : " << short_word << endl;
cout << "long word : " << long_word << endl;
return 0;
}
Test 14.40
class comparestr
{
public:
bool operator()(const string& s1, const string& s2) { return s1.size() < s2.size(); };
};
class comparesz
{
public:
comparesz(const vector<string>::size_type& s) : sz(s) {};
bool operator()(const string& s1) { return s1.size() >= sz; };
private:
vector<string>::size_type sz;
};
void bigges(vector<string>& words, vector<string>::size_type& sz)
{
elimDups(words);
stable_sort(words.begin(), words.end(), [](const string& s1, const string& s2) {return s1.size() < s2.size(); });
auto it = find_if(words.begin(), words.end(), [sz](const string& s1) {return s1.size() >= sz; });
auto cnt = words.end() - it;
cout << cnt << (cnt > 1 ? " words" : " word") << " of length " << sz << " or longer" << endl;
for_each(it, words.end(), [](const string& s) {cout << s << " "; }); cout << endl;
}
Test 14.42
int main()
{
using std::placeholders::_1;
vector<int> ivec{ 1001, 2001, 1002, 3002, 4396 };
vector<string> svec{ "pooh", "pooh", "pooh", "wg", "hs" };
cout << count_if(ivec.begin(), ivec.end(), bind(greater<int>(), _1, 1024)) << endl;
cout << *find_if(svec.begin(), svec.end(), bind(not_equal_to<string>(), _1, "pooh")) << endl;
multiplies<int> mulit;
for (auto& i : ivec)
i = mulit(i, 2);
for (auto& i : ivec)
cout << i << endl;
return 0;
}
Test 14.43
bool calmodulus(const int& ival, const vector<int>& ivec)
{
modulus<int> intMod;
for (auto& i : ivec)
if (intMod(ival, i) != 0)
return false;
return true;
}
Test 14.44
int add(int i, int j)
{
return i + j;
}
auto mod = [](int i, int j) {return i % j; };
struct divide
{
int operator()(int i, int j) { return i / j; };
};
int main()
{
map<string, function<int(int, int)>> binops = {
{"+", add},
{"-", std::minus<int>()},
{"*", [](int i, int j) {return i * j; }},
{"/", divide()},
{"%", mod}
};
return 0;
}
Test 14.45
class my_sales_data
{
public:
explicit operator std::string() const { return bookNo; };
explicit operator double() const { return revenue; };
private:
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
Test 14.53
class SmallInt
{
friend SmallInt operator+(const SmallInt&, const SmallInt&);
public:
SmallInt(int = 0);
operator int() const {
return val;
};
private:
size_t val;
};
int main()
{
SmallInt s1;
double d = s1 + SmallInt(3.14);
return 0;
}