泛型编程的关键概念:
在循环遍历容器时C++常使用!=运算符而不是<运算符,这是因为!=和==对于标准库的所有容器都有效,而<大多数都没有定义。
function_template.h
template <typename T>
T compare(const T &v1, const T &v2) {
if (v1 < v2) return v2;
if (v2 < v1) return v1;
return v1;
}
template <typename Itr, typename Val>
Itr find(Itr beg, Itr end, Val v) {
while (beg != end) {
if (*beg == v) {
break;
} else {
++beg;
}
}
return beg;
}
template <typename T, size_t N>
void print(const T (&a)[N]) { // array reference that contain size information
for (size_t i = 0; i < N; ++i) {
std::cout << a[i] << std::endl;
}
}
template <typename T, size_t N>
T *begin(const T (&arr)[N]) {
return &arr[0];
}
template <typename T, size_t N>
T *end(const T (&arr)[N]) {
return &(arr+N);
}
template <typename T, size_t N>
constexpr size_t arr_size(const T (&arr)[N]) {
return N;
}
Sales_item.h
#pragma once
#include <iostream>
#include <string>
class Sales_item {
friend std::ostream &operator<<(std::ostream &out, const Sales_item &s);
friend std::istream &operator>>(std::istream &in, Sales_item &s);
friend bool operator==(const Sales_item &lhs, const Sales_item &rhs);
friend bool operator!=(const Sales_item &lhs, const Sales_item &rhs);
friend bool operator<(const Sales_item &lhs, const Sales_item &rhs);
public:
Sales_item() :bookNo(), unit_sold(0), revenue(0) {};
Sales_item(const std::string &s, unsigned n, double v)
: bookNo(s), unit_sold(n), revenue(v) {}
Sales_item(const std::string &s) : bookNo(s), unit_sold(0), revenue(0) {};
Sales_item(const Sales_item &obj) : bookNo(obj.bookNo), unit_sold(obj.unit_sold), revenue(obj.revenue) {}
Sales_item(std::istream &in) {
in >> bookNo >> unit_sold >> revenue;
}
Sales_item operator+=(const Sales_item &);
Sales_item &operator=(const std::string &s);
Sales_item &operator=(const Sales_item &s);
std::string get_boolNo() const;
double avg_price() const;
private:
std::string bookNo;
unsigned unit_sold;
double revenue;
};
Sales_item operator+(const Sales_item &lhs, const Sales_item &rhs);
Sales_item.cpp
#include "Sales_item.h"
std::ostream &operator<<(std::ostream &out, const Sales_item &s) {
out << s.bookNo << " " << s.revenue << " " << s.unit_sold << s.avg_price();
return out;
}
std::istream &operator>>(std::istream &in, Sales_item &s) {
double price;
in >> s.bookNo >> s.unit_sold >> price;
if (in) {
s.revenue = s.unit_sold * price;
} else {
s = Sales_item();
}
return in;
}
bool operator==(const Sales_item &lhs, const Sales_item &rhs) {
return
lhs.bookNo == rhs.bookNo &&
lhs.unit_sold == rhs.unit_sold &&
lhs.revenue == rhs.revenue;
}
bool operator!=(const Sales_item &lhs, const Sales_item &rhs) {
return !(lhs == rhs);
}
bool operator<(const Sales_item &lhs, const Sales_item &rhs) {
return lhs.revenue < rhs.revenue;
}
Sales_item Sales_item::operator+=(const Sales_item &s) {
Sales_item ret;
ret.bookNo = bookNo;
ret.unit_sold = unit_sold + s.unit_sold;
ret.revenue = revenue + s.revenue;
return ret;
}
Sales_item &Sales_item::operator=(const std::string &s) {
Sales_item tmp(s);
*this = tmp;
return *this;
}
Sales_item &Sales_item::operator=(const Sales_item &s) {
bookNo = s.bookNo;
unit_sold = s.unit_sold;
revenue = s.revenue;
return *this;
}
std::string Sales_item::get_boolNo() const {
return bookNo;
}
double Sales_item::avg_price() const {
return revenue/unit_sold;
}
Sales_item operator+(const Sales_item &lhs, const Sales_item &rhs) {
Sales_item ret;
ret+=lhs;
ret+=rhs;
return ret;
}