18.3:
方法1 : 用一个类封装起来
class pointerArr
{
public:
void pointerArr(int * pt) : p(pt) { }
~pointerArr() { delete [] p; }
private:
int * p;
}
void exercise(int * b, int * e)
{
vector<int> v(b, e);
pointerArr p = new int[v.size()];
ifstream in("ints");
}
方法2 : 在本函数内进行处理
void exercise(int * b, int * e)
{
int *p =new int[v.size()];
try
{
vector<int> v(b, e);
ifstream in("ints");
}
catch(someErr r)
{
delete [] p;
}
}
18.5:
#include<iostream>
using namespace std;
int main()
{
try {
}
catch (const overflow_error& e)
{
cout << e.what();
abort();
}
catch (const logic_error& e)
{
cout << e.what();
abort();
}
catch (exception& e)
{
cout << e.what();
abort();
}
return 0;
}
18.8:
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<fstream>
#include<vector>
#include<algorithm>
#include<tuple>
#include<numeric>
template<class T>class std::hash;
class Sales_data
{
friend class std::hash<Sales_data>;
friend istream& read(istream& is, Sales_data& item);
friend ostream& print(ostream& os, const Sales_data& item);
friend Sales_data add(const Sales_data& s1, const Sales_data& s2);
friend istream& operator>>(istream& , Sales_data&);
friend ostream& operator<<(ostream& , const Sales_data&);
friend Sales_data operator+(const Sales_data& s1, const Sales_data& s2);
friend Sales_data operator-(const Sales_data& s1, const Sales_data& s2);
friend bool operator==(const Sales_data& lhs, const Sales_data& rhs);
public:
Sales_data() noexcept= default;
Sales_data(const string& s)noexcept :bookNo(s) {};
Sales_data(const string& s, unsigned n, double p)noexcept :bookNo(s), unit_sold(n), revenue(n* p) {};
Sales_data(istream& is) noexcept { read(cin, *this); }
Sales_data& operator+=(const Sales_data& s);
Sales_data& operator-=(const Sales_data& s);
Sales_data& operator=(const string& s);
explicit operator string() const { return this->bookNo; }
explicit operator double() const { return this->avg_price(); }
Sales_data& combine(const Sales_data& rhs);
string isbn()const
{
return this->bookNo;
}
private:
inline double avg_price()const;
string bookNo;
unsigned unit_sold = 0;
double revenue = 0.0;
};
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
this->unit_sold += rhs.unit_sold;
this->revenue += rhs.revenue;
return *this;
}
Sales_data add(const Sales_data& s1, const Sales_data& s2)
{
Sales_data temp = s1;
temp.combine(s2);
return temp;
}
istream& read(istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.unit_sold >> price;
item.revenue = item.unit_sold * price;
return is;
}
ostream& print(ostream& os, const Sales_data& item)
{
os << item.bookNo << " " << item.unit_sold << " " << item.revenue;
return os;
}
inline double Sales_data::avg_price()const
{
return unit_sold ? revenue / unit_sold : 0;
}
istream& operator>>(istream& in, Sales_data& sd)
{
double price = 0;
in >> sd.bookNo >> sd.unit_sold >> price;
if (in)
{
sd.revenue = sd.unit_sold * price;
}
else
{
sd = Sales_data();
}
return in;
}
ostream& operator<<(ostream& out, const Sales_data& item)
{
out << item.bookNo << " " << item.unit_sold << " " << item.revenue << " " << item.avg_price();
return out;
}
Sales_data operator+(const Sales_data& s1, const Sales_data & s2)
{
Sales_data temp = s1;
temp.unit_sold += s2.unit_sold;
temp.revenue += s2.revenue;
return temp;
}
Sales_data& Sales_data::operator+=(const Sales_data& s)
{
this->unit_sold += s.unit_sold;
this->revenue += s.revenue;
return *this;
}
Sales_data operator-(const Sales_data& s1, const Sales_data& s2)
{
Sales_data temp = s1;
temp -= s2;
return temp;
}
Sales_data& Sales_data::operator-=(const Sales_data& s)
{
this->unit_sold -= s.unit_sold;
this->revenue -= s.revenue;
return *this;
}
Sales_data& Sales_data::operator=(const string& s)
{
*this = Sales_data(s);
return *this;
}
bool operator==(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() == rhs.isbn() && lhs.revenue == rhs.revenue && lhs.unit_sold == rhs.unit_sold;
}
bool operator!=(const Sales_data& lhs, const Sales_data& rhs)
{
return !(lhs == rhs);
}
namespace std
{
template<>
struct hash<Sales_data>
{
typedef size_t result_type;
typedef Sales_data argument_type;
size_t operator() (const Sales_data& s)const;
};
size_t hash<Sales_data>::operator() (const Sales_data& s)const
{
return hash<string>()(s.bookNo) ^
hash<unsigned>()(s.unit_sold) ^
hash<double>()(s.revenue);
}
}
bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() < rhs.isbn();
}
typedef pair<vector<Sales_data>::size_type,
pair<vector<Sales_data>::const_iterator,
vector<Sales_data>::const_iterator>> matches;
vector<matches> findBook(const vector<vector<Sales_data>>& files, const string& s)
{
vector<matches> ret;
for (auto it = files.cbegin(); it != files.cend(); ++it)
{
auto found = equal_range(it->cbegin(), it->cend(), s, compareIsbn);
if (found.first != found.second)
{
ret.push_back(make_pair(it - files.cbegin(), make_pair(found.first, found.second)));
}
}
return ret;
}
void reportResults(istream& in, ostream& os,
const vector<vector<Sales_data>>& files)
{
string s;
while (cin >> s)
{
auto trans = findBook(files, s);
if (trans.empty())
{
os << s << " not found" << endl;
continue;
}
for (const auto& store : trans)
{
os << "store " << store.first << " sales: "
<< accumulate(store.second.first, store.second.second,
Sales_data(s))
<< endl;
}
}
}
18.9:
#pragma once
#include<iostream>
using namespace std;
#include<string>
#include<fstream>
#include<vector>
#include<algorithm>
#include<tuple>
#include<numeric>
class out_of_stock :public runtime_error
{
public:
explicit out_of_stock(const string& s)
:runtime_error(s) {}
};
class isbn_mismatch :public logic_error
{
public:
explicit isbn_mismatch(const string& s) :logic_error(s) {}
isbn_mismatch(const string& s, const string& lhs, const string& rhs) :
logic_error(s), left(lhs), right(rhs) {}
const string left, right;
};
template<class T>class std::hash;
class Sales_data
{
friend class std::hash<Sales_data>;
friend istream& read(istream& is, Sales_data& item);
friend ostream& print(ostream& os, const Sales_data& item);
friend Sales_data add(const Sales_data& s1, const Sales_data& s2);
friend istream& operator>>(istream& , Sales_data&);
friend ostream& operator<<(ostream& , const Sales_data&);
friend Sales_data operator+(const Sales_data& s1, const Sales_data& s2);
friend Sales_data operator-(const Sales_data& s1, const Sales_data& s2);
friend bool operator==(const Sales_data& lhs, const Sales_data& rhs);
public:
Sales_data() noexcept= default;
Sales_data(const string& s)noexcept :bookNo(s) {};
Sales_data(const string& s, unsigned n, double p)noexcept :bookNo(s), unit_sold(n), revenue(n* p) {};
Sales_data(istream& is) noexcept { read(cin, *this); }
Sales_data& operator+=(const Sales_data& s);
Sales_data& operator-=(const Sales_data& s);
Sales_data& operator=(const string& s);
explicit operator string() const { return this->bookNo; }
explicit operator double() const { return this->avg_price(); }
Sales_data& combine(const Sales_data& rhs);
string isbn()const
{
return this->bookNo;
}
private:
inline double avg_price()const;
string bookNo;
unsigned unit_sold = 0;
double revenue = 0.0;
};
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
this->unit_sold += rhs.unit_sold;
this->revenue += rhs.revenue;
return *this;
}
Sales_data add(const Sales_data& s1, const Sales_data& s2)
{
Sales_data temp = s1;
temp.combine(s2);
return temp;
}
istream& read(istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.unit_sold >> price;
item.revenue = item.unit_sold * price;
return is;
}
ostream& print(ostream& os, const Sales_data& item)
{
os << item.bookNo << " " << item.unit_sold << " " << item.revenue;
return os;
}
inline double Sales_data::avg_price()const
{
return unit_sold ? revenue / unit_sold : 0;
}
istream& operator>>(istream& in, Sales_data& sd)
{
double price = 0;
in >> sd.bookNo >> sd.unit_sold >> price;
if (in)
{
sd.revenue = sd.unit_sold * price;
}
else
{
sd = Sales_data();
}
return in;
}
ostream& operator<<(ostream& out, const Sales_data& item)
{
out << item.bookNo << " " << item.unit_sold << " " << item.revenue << " " << item.avg_price();
return out;
}
Sales_data operator+(const Sales_data& s1, const Sales_data & s2)
{
Sales_data temp = s1;
temp.unit_sold += s2.unit_sold;
temp.revenue += s2.revenue;
return temp;
}
Sales_data& Sales_data::operator+=(const Sales_data& s)
{
if (isbn() != s.isbn())
{
throw isbn_mismatch("wrong isbns", isbn(), s.isbn());
}
this->unit_sold += s.unit_sold;
this->revenue += s.revenue;
return *this;
}
Sales_data operator-(const Sales_data& s1, const Sales_data& s2)
{
Sales_data temp = s1;
temp -= s2;
return temp;
}
Sales_data& Sales_data::operator-=(const Sales_data& s)
{
this->unit_sold -= s.unit_sold;
this->revenue -= s.revenue;
return *this;
}
Sales_data& Sales_data::operator=(const string& s)
{
*this = Sales_data(s);
return *this;
}
bool operator==(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() == rhs.isbn() && lhs.revenue == rhs.revenue && lhs.unit_sold == rhs.unit_sold;
}
bool operator!=(const Sales_data& lhs, const Sales_data& rhs)
{
return !(lhs == rhs);
}
namespace std
{
template<>
struct hash<Sales_data>
{
typedef size_t result_type;
typedef Sales_data argument_type;
size_t operator() (const Sales_data& s)const;
};
size_t hash<Sales_data>::operator() (const Sales_data& s)const
{
return hash<string>()(s.bookNo) ^
hash<unsigned>()(s.unit_sold) ^
hash<double>()(s.revenue);
}
}
bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() < rhs.isbn();
}
typedef pair<vector<Sales_data>::size_type,
pair<vector<Sales_data>::const_iterator,
vector<Sales_data>::const_iterator>> matches;
vector<matches> findBook(const vector<vector<Sales_data>>& files, const string& s)
{
vector<matches> ret;
for (auto it = files.cbegin(); it != files.cend(); ++it)
{
auto found = equal_range(it->cbegin(), it->cend(), s, compareIsbn);
if (found.first != found.second)
{
ret.push_back(make_pair(it - files.cbegin(), make_pair(found.first, found.second)));
}
}
return ret;
}
void reportResults(istream& in, ostream& os,
const vector<vector<Sales_data>>& files)
{
string s;
while (cin >> s)
{
auto trans = findBook(files, s);
if (trans.empty())
{
os << s << " not found" << endl;
continue;
}
for (const auto& store : trans)
{
os << "store " << store.first << " sales: "
<< accumulate(store.second.first, store.second.second,
Sales_data(s))
<< endl;
}
}
}
.cpp:
#include<iostream>
#include<vector>
#include<string>
#include "Sales_data.h"
int main()
{
Sales_data item1, item2, sum;
while (std::cin >> item1 >> item2)
{
try
{
sum = item1;
sum += item2;
std::cout << sum << std::endl;
}
catch (const isbn_mismatch& e)
{
std::cerr << e.what() << ": left isbn(" << e.left << ") right isbn(" << e.right << ")" << std::endl;
}
}
return 0;
}
18.14:
namespace mathLib
{
namespace MatrixLib
{
class matrix
{
};
matrix operator* (const matrix&, const matrix&);
}
}
mathLib::MatrixLib::matrix mathLib::MatrixLib::operator* (const matrix&, const matrix&);
rix mathLib::MatrixLib::operator* (const matrix&, const matrix&);
18.17:
using声明位置1:
#include<iostream>
namespace Exercise
{
int ivar = 0;
double dvar = 0;
const int limit = 0;
}
int ivar = 0;
//using Exercise::ivar;报错
using Exercise::dvar;
using Exercise::limit;
void manip()
{
double dvar = 3.1416;
int iobj = limit + 1;
++ivar;
++::ivar;
}
int main()
{
return 0;
}
using声明位置2:
#include<iostream>
namespace Exercise
{
int ivar = 0;
double dvar = 0;
const int limit = 0;
}
int ivar = 0;
void manip()
{
using Exercise::ivar;
using Exercise::dvar;
using Exercise::limit;
//double dvar = 3.1416;重定义
int iobj = limit + 1;
++ivar;
++::ivar;
}
int main()
{
return 0;
}
using指示位置1:
#include<iostream>
namespace Exercise
{
int ivar = 0;
double dvar = 0;
const int limit = 0;
}
int ivar = 0;
using namespace Exercise;
void manip()
{
double dvar = 3.1416;
int iobj = limit + 1;
//++ivar;二义性
++::ivar;
}
int main()
{
return 0;
}
using指示位置2:
#include<iostream>
namespace Exercise
{
int ivar = 0;
double dvar = 0;
const int limit = 0;
}
int ivar = 0;
void manip()
{
using namespace Exercise;
double dvar = 3.1416;
int iobj = limit + 1;
//++ivar;
++::ivar;
}
int main()
{
return 0;
}
18.27:
#include <iostream>
#include <vector>
struct Base1 {
void print(int) const {
std::cout << "Base1 Print Used" << std::endl;
};
protected:
int ival;
double dval;
char cval;
private:
int* id;
};
struct Base2 {
void print(double) const;
protected:
double fval;
private:
double dval;
};
struct Derived : public Base1 {
void print(std::string) const;
protected:
std::string sval = std::string(1, Base1::cval);//(e)
double dval;
};
struct MI : public Derived, public Base2 {
void print(std::vector<double>) {};
void print(int x) {
Base1::print(x);
}
int ival;
double dval;
void foo(double cval)
{
int dval;
dval = Base1::dval + Derived::dval;//(c)
Base2::fval = dvec.back() - 1;//(d)
Derived::sval[0] = Base1::cval;//(e)
std::cout << dval;
}
protected:
std::vector<double> dvec = { 9,8,7 };
};
int main()
{
MI mi;
return 0;
}
18.30:
#include <iostream>
using namespace std;
class Class {
};
class Base : public Class {
public:
// Base() = default;
Base() { cout << "Base()" << endl; }
Base(int) { cout << "Base(int)" << endl; }
Base(const Base& b) {}
};
class D1 : virtual public Base {
public:
D1() = default;
D1(int i) : Base(i) { cout << "D1(int)" << endl; }
D1(const D1& d) {}
};
class D2 : virtual public Base {
public:
D2() = default;
D2(int i) : Base(i) { cout << "D2(int)" << endl; }
D2(const D2& d) {}
};
class MI : public D1, public D2 {
public:
MI() = default;
MI(int i) : D1(i), D2(i) { cout << "MI(int)" << endl; }
MI(const MI& m) {}
};
class Final : public MI, public Class {
public:
Final() = default;
// Final(int i) : MI(i) { cout << "Final(int)" << endl; }
Final(int i) : MI(i), Base(i) { cout << "Final(int)" << endl; }
Final(const Final& f) {}
};
int main(int argc, char const* argv[])
{
Final f(1);
return 0;
}