提交 73363b60 编写于 作者: J jzplp

14.1-14.12

上级 66c70db9
#ifndef TREE_H
#define TREE_H
#include<iostream>
class Tree
{
friend bool operator==(const Tree & t1, const Tree & t2);
friend std::ostream & operator<<(std::ostream & os, const Tree & t);
friend std::istream & operator>>(std::istream & is, Tree & t);
public:
Tree() : Tree(0, nullptr, nullptr) { }
Tree(int d) : Tree(d, nullptr, nullptr) { }
Tree(int d, Tree * l, Tree * r) : data(d), left(l), right(r) { }
private:
int data = 0;
Tree * left = nullptr;
Tree * right = nullptr;
};
bool operator==(const Tree & t1, const Tree & t2)
{
if(t1.data == t2.data && t1.left == t2.left && t1.right == t2.right )
return true;
return false;
}
std::ostream & operator<<(std::ostream & os, const Tree & t)
{
os << t.data;
return os;
}
std::istream & operator>>(std::istream & is, Tree & t)
{
is >> t.data;
if(!is)
t.data = 0;
return is;
}
#endif
#include <iostream>
#include <string>
#include "Tree.h"
int main()
{
Tree t1(1), t2(2), t3;
std::cin >> t3;
std::cout << t3 << std::endl;
std::cout << (t1 == t2) << std::endl;
std::cout << t1 << " " << t2 << std::endl;
return 0;
}
#include <iostream>
#include <string>
#include "Sales_data.h"
Sales_data & Sales_data::operator+=(const Sales_data & sa)
{
amount += sa.amount;
totalPrice += sa.totalPrice;
return *this;
}
inline double Sales_data::avg_price() const
{
if(amount)
return totalPrice / amount;
return 0;
}
Sales_data operator+(const Sales_data & sa, const Sales_data & sb)
{
Sales_data sum = sa;
sum += sb;
return sum;
}
std::istream & operator>>(std::istream & is, Sales_data & sa)
{
double price = 0;
is >> sa.ISBN >> sa.amount >> price;
sa.totalPrice = price * sa.amount;
return is;
}
std::ostream & operator<<(std::ostream & os, const Sales_data & sa)
{
os << sa.isbn() << " " << sa.amount << " " << sa.totalPrice << " " << sa.avg_price();
return os;
}
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <iostream>
#include<string>
struct Sales_data;
Sales_data operator+(const Sales_data & sa, const Sales_data & sb);
std::istream & operator>>(std::istream & is, Sales_data & sa);
std::ostream & operator<<(std::ostream & os, const Sales_data & sa);
class Sales_data
{
friend Sales_data operator+(const Sales_data & sa, const Sales_data & sb);
friend std::istream & operator>>(std::istream & is, Sales_data & sa);
friend std::ostream & operator<<(std::ostream & os, const Sales_data & sa);
public:
Sales_data() = default;
Sales_data(const std::string &s) : ISBN(s) { }
Sales_data(const std::string &s, int a, double t) : ISBN(s), amount(a), totalPrice(t * a) { }
Sales_data(std::istream &is)
{
is >> *this;
}
std::string isbn() const
{
return ISBN;
}
Sales_data & operator+=(const Sales_data & sa);
private:
std::string ISBN;
double totalPrice = 0.0;
int amount = 0;
inline double avg_price() const;
};
#endif
#include <iostream>
#include <string>
#include "Sales_data.h"
int main()
{
Sales_data total(std::cin);
if(std::cin)
{
Sales_data trans;
while(std::cin >> trans)
{
if(total.isbn() == trans.isbn())
total += trans;
else
{
std::cout << total << std::endl;
total = trans;
}
}
std::cout << total << std::endl;
}
else
{
std::cerr << "No data?!" <<std::endl;
return -1;
}
return 0;
}
#ifndef TREE_H
#define TREE_H
class Tree
{
friend bool operator==(const Tree & t1, const Tree & t2);
public:
Tree() : Tree(0, nullptr, nullptr) { }
Tree(int d) : Tree(d, nullptr, nullptr) { }
Tree(int d, Tree * l, Tree * r) : data(d), left(l), right(r) { }
private:
int data = 0;
Tree * left = nullptr;
Tree * right = nullptr;
};
bool operator==(const Tree & t1, const Tree & t2)
{
if(t1.data == t2.data && t1.left == t2.left && t1.right == t2.right )
return true;
return false;
}
#endif
#include <iostream>
#include <string>
#include "Tree.h"
int main()
{
Tree t1(1), t2(2);
std::cout << (t1 == t2) << std::endl;
return 0;
}
#include <memory>
#include<utility>
#include<algorithm>
#include<iostream>
#include "String.h"
std::allocator<char> String::alloc;
void String::chk_n_alloc()
{
if(size() == capacity())
reallocate();
}
void String::push_back(char c)
{
chk_n_alloc();
alloc.construct(first_free++, c);
}
std::pair<char *, char *> String::alloc_n_copy(const char * b, const char * e)
{
char * data = alloc.allocate(e - b);
return {data, std::uninitialized_copy(b, e, data)};
}
void String::free()
{
if(elements)
{
std::for_each(elements, first_free, [](char &c){ alloc.destroy(&c); });
alloc.deallocate(elements, cap - elements);
}
}
void String::reallocate()
{
size_t newcapacity = size() ? 2 * size() : 1;
reserve(newcapacity);
}
void String::reserve(size_t n)
{
if(n <= capacity())
return;
char * newdata = alloc.allocate(n);
char * dest = newdata;
char * elem = elements;
for(size_t i = 0;i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + n;
}
void String::resize(size_t n, char c)
{
if(n == size())
return;
if(n < size())
{
while(size() != n)
alloc.destroy(--first_free);
return;
}
if(n > capacity())
reserve(n);
while(size() != n)
alloc.construct(first_free++, c);
}
String::String(const String & s)
{
std::pair<char *, char *> newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
String & String::operator=(const String & rhs)
{
std::pair<char *, char *> data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
String::String(const char *ps)
{
const char *p = ps;
while(*p != '\0')
++p;
std::pair<char *, char *> newdata = alloc_n_copy(ps, p);
elements = newdata.first;
first_free = cap = newdata.second;
}
String::String(String &&s) noexcept : elements(s.elements), first_free(s.first_free), cap(s.cap)
{
s.elements = s.first_free = s.cap = nullptr;
}
String & String::operator=(String && rhs) noexcept
{
if(this != &rhs)
{
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
std::ostream & operator<<(std::ostream &os, const String & s)
{
for(char *p = s.begin(); p != s.end(); ++p)
os << *p;
return os;
}
#ifndef DEMO_STRING_H
#define DEMO_STRING_H
#include<memory>
#include<utility>
#include<iostream>
class String
{
friend std::ostream & operator<<(std::ostream &os, const String & s);
public:
String() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
String(const char *);
~String() { free(); }
String(const String &);
String & operator=(const String & rhs);
String(String &&s) noexcept;
String & operator=(String && rhs) noexcept;
void push_back(char c);
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
char * begin() const { return elements; }
char * end() const { return first_free; }
void reserve(size_t n);
void resize(size_t n, char c = '\0');
private:
void chk_n_alloc();
std::pair<char *, char *> alloc_n_copy(const char *, const char *);
void free();
void reallocate();
static std::allocator<char> alloc;
char * elements;
char * first_free;
char * cap;
};
std::ostream & operator<<(std::ostream &os, const String & s);
#endif
#include<iostream>
#include<vector>
#include<utility>
#include "String.h"
int main()
{
String s1("12345");
String s = s1;
s = s;
s.push_back('6');
s.push_back('7');
s.resize(2);
std::cout << s << std::endl;
std::vector<String> v; v.push_back(s1);
v.push_back("1234");
v.push_back(s);
for(String & i : v)
{
std::cout << i << std::endl;
}
String s5(std::move(s1));
std::cout << s5 << std::endl;
s = std::move(s5);
std::cout << s << std::endl;
return 0;
}
#ifndef TREE_H
#define TREE_H
#include<iostream>
class Tree
{
friend bool operator==(const Tree & t1, const Tree & t2);
friend std::ostream & operator<<(std::ostream & os, const Tree & t);
public:
Tree() : Tree(0, nullptr, nullptr) { }
Tree(int d) : Tree(d, nullptr, nullptr) { }
Tree(int d, Tree * l, Tree * r) : data(d), left(l), right(r) { }
private:
int data = 0;
Tree * left = nullptr;
Tree * right = nullptr;
};
bool operator==(const Tree & t1, const Tree & t2)
{
if(t1.data == t2.data && t1.left == t2.left && t1.right == t2.right )
return true;
return false;
}
std::ostream & operator<<(std::ostream & os, const Tree & t)
{
os << t.data;
return os;
}
#endif
#include <iostream>
#include <string>
#include "Tree.h"
int main()
{
Tree t1(1), t2(2);
std::cout << (t1 == t2) << std::endl;
std::cout << t1 << " " << t2 << std::endl;
return 0;
}
#include <iostream>
#include <string>
#include "Sales_data.h"
Sales_data & Sales_data::operator+=(const Sales_data & sa)
{
amount += sa.amount;
totalPrice += sa.totalPrice;
return *this;
}
inline double Sales_data::avg_price() const
{
if(amount)
return totalPrice / amount;
return 0;
}
Sales_data operator+(const Sales_data & sa, const Sales_data & sb)
{
Sales_data sum = sa;
sum += sb;
return sum;
}
std::istream & operator>>(std::istream & is, Sales_data & sa)
{
double price = 0;
is >> sa.ISBN >> sa.amount >> price;
if(is)
sa.totalPrice = price * sa.amount;
else
sa = Sales_data();
return is;
}
std::ostream & operator<<(std::ostream & os, const Sales_data & sa)
{
os << sa.isbn() << " " << sa.amount << " " << sa.totalPrice << " " << sa.avg_price();
return os;
}
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <iostream>
#include<string>
struct Sales_data;
Sales_data operator+(const Sales_data & sa, const Sales_data & sb);
std::istream & operator>>(std::istream & is, Sales_data & sa);
std::ostream & operator<<(std::ostream & os, const Sales_data & sa);
class Sales_data
{
friend Sales_data operator+(const Sales_data & sa, const Sales_data & sb);
friend std::istream & operator>>(std::istream & is, Sales_data & sa);
friend std::ostream & operator<<(std::ostream & os, const Sales_data & sa);
public:
Sales_data() = default;
Sales_data(const std::string &s) : ISBN(s) { }
Sales_data(const std::string &s, int a, double t) : ISBN(s), amount(a), totalPrice(t * a) { }
Sales_data(std::istream &is)
{
is >> *this;
}
std::string isbn() const
{
return ISBN;
}
Sales_data & operator+=(const Sales_data & sa);
private:
std::string ISBN;
double totalPrice = 0.0;
int amount = 0;
inline double avg_price() const;
};
#endif
#include <iostream>
#include <string>
#include "Sales_data.h"
int main()
{
Sales_data total(std::cin);
if(std::cin)
{
Sales_data trans;
while(std::cin >> trans)
{
if(total.isbn() == trans.isbn())
total += trans;
else
{
std::cout << total << std::endl;
total = trans;
}
}
std::cout << total << std::endl;
}
else
{
std::cerr << "No data?!" <<std::endl;
return -1;
}
return 0;
}
* **练习14.1**
重载的运算符和内置运算符在对象求值顺序和短路求值属性上不同。
在优先级和结合律,运算对象的数量上相同。
* **练习14.2**
Sales_data类 书上的版本
添加了重载的输入,输出,加法和复合赋值运算符
[14.2 Sales_data.h程序代码](14.2/Sales_data.h)
[14.2 Sales_data.cpp程序代码](14.2/Sales_data.cpp)
[14.2 测试程序代码](14.2/main.cpp)
* **练习14.3**
(a) 使用const char *
(b) 使用string的
(c) 使用vector的,在vector内部使用string的
(d) 使用string的
* **练习14.4**
(a) 非成员
(b) 成员
(c) 成员
(d) 成员