c++ primer中文版第五版作业第十八章

仓库地址

文章目录

      • 18.1
      • 18.2
      • 18.3
      • 18.4
      • 18.5
      • 18.6
      • 18.7
      • 18.8
      • 18.9
      • 18.10
      • 18.11
      • 18.12
      • 18.13
      • 18.14
      • 18.15
      • 18.16
        • 位置一
          • using声明
        • 位置二
          • using声明
        • 位置一
          • using指示
        • 位置二
          • using指示
      • 18.17
      • 18.18
      • 18.19
      • 18.20
      • 18.21
      • 18.22
      • 18.23
      • 18.24
      • 18.25
      • 18.26
      • 18.26
      • 18.28
      • 18.29
      • 18.30

18.1

  1. 此时r是一个range_error类型的局部对象
  2. 此时p是exception类型的指针,指向局部对象r
    如果throw p就会抛出一个指向局部对象的指针,那么有可能在执行catch语句之前,该局部对象已经被销毁。

18.2

 v和in可以调用其析构函数释放资源,而p无法正确释放资源,导致内存泄漏。

18.3

  1. 使用智能指针管理p
    unique_ptr<int []> p(new int[v.size()])
  2. 使用类来控制资源的分配
class ptr
{public:explicit ptr(size_t len):p(new int[len]) {}ptr(const ptr&)=delete;ptr & operator=(const ptr&)=delete;~ptr(){delete [] p;}private:int *p;
};

18.4

catch语句是按照其出现的顺序逐一进行匹配的,所以根据继承体系catch(exception)后面的catch子句永远无法被匹配到。

try{
//
}catch(overflow_error eobj){
//
}catch(const runtime_error &re){
//
}catch(exception){/**/}

18.5

#include <iostream>
#include <exception>
#include <stdexcept>
#include <cstdlib>
int main(){try{//使用c++标准库
}catch(const exception &e){std::cout<<e.what()<<std::endl;abort();
}
}

18.6

  1. throw exceptionType * eobj,注意不能抛出一个指向局部对象的指针
  2. 抛出的所有异常都能被捕获
  3. int a=1;throw a;抛出的所有int类型值都能被捕获,但是其余的整型类型无法进行算数类型转换为int。

18.7

#ifndef BLOB_H
#define BLOB_H
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <string>
#include <initializer_list>
#include <stdexcept>
template <typename> class BlobPtr;
template <typename> class Blob;
//Blob
template <typename T> bool operator==(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator!=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>=(const Blob<T> &,const Blob<T> &);
template <typename T> class Blob
{friend class BlobPtr<T>;friend bool operator==<T>(const Blob<T> &,const Blob<T> &);friend bool operator!=<T>(const Blob<T> &,const Blob<T> &);friend bool operator< <T>(const Blob<T> &,const Blob<T> &);friend bool operator<= <T>(const Blob<T> &,const Blob<T> &);friend bool operator> <T>(const Blob<T> &,const Blob<T> &);friend bool operator>= <T>(const Blob<T> &,const Blob<T> &);public:typedef T value_type;typedef typename std::vector<T>::size_type size_type;Blob() try:data(std::make_shared<std::vector<T>>()){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(std::initializer_list<T> il) try:data(std::make_shared<std::vector<T>>(il)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(const Blob &org) try:data(std::make_shared<std::vector<T>>(*org.data)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}template <typename it> Blob(it b,it e) try:data(std::make_shared<std::vector<T>>(b,e)) {} catch(std::bad_alloc &ba){std::cout<<ba.what()<<std::endl;}Blob &operator=(const Blob &);T & operator[](size_type i);const T & operator[](size_type i) const;size_type size() const {return data->size();}bool empty() const {return data->empty;}void push_back(const T &t){data->push_back(t);}void push_back(T &&t){data->push_back(std::move(t));}void pop_back();T & front();T & back();const T & front() const;const T & back() const;BlobPtr<T> begin();BlobPtr<T> end();private:std::shared_ptr<std::vector<T>> data;void check(size_type i,const std::string &msg) const;
};
//BlobPtr
template <typename T> bool operator==(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator!=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> class BlobPtr
{friend bool operator==<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator!=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator< <T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator<=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator><T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator>=<T>(const BlobPtr<T> &,const BlobPtr<T> &);public:typedef typename std::vector<T>::size_type size_type;BlobPtr():curr(0){}BlobPtr(const Blob<T> &blob,size_type sz=0):wptr(blob.data),curr(sz){}T & operator[](size_type i);const T & operator[](size_type i) const;BlobPtr & operator++();BlobPtr & operator++(int);BlobPtr & operator--();BlobPtr & operator--(int);BlobPtr operator+(size_type) const;BlobPtr operator-(size_type) const;BlobPtr operator+=(size_type) const;BlobPtr operator-=(size_type) const;T & operator*() const;T * operator->() const;private:std::shared_ptr<std::vector<T>> check(size_type i,const std::string &msg) const;std::weak_ptr<std::vector<T>> wptr;size_type curr=0;
};
//Blob
template <typename T> Blob<T> & Blob<T>::operator=(const Blob &rhs)
{data=std::make_shared<std::vector<T>>(*rhs.data);return *this;
}
template <typename T> T & Blob<T>::operator[](size_type i)
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> const T & Blob<T>::operator[](size_type i) const
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> void Blob<T>::pop_back()
{check(0,"pop_back on empty Blob");data->pop_back();
}
template <typename T> T & Blob<T>::front()
{check(0,"front on empty Blob");return data->front();
}
template <typename T> const T & Blob<T>::front() const
{check(0,"front on empty Blob");return data->front();
}
template <typename T> T & Blob<T>::back()
{check(0,"back on empty Blob");return data->back();
}
template <typename T> const T & Blob<T>::back() const
{check(0,"back on empty Blob");return data->back();
}
template <typename T> BlobPtr<T> Blob<T>::begin()
{return BlobPtr<T>(*this);
}
template <typename T> BlobPtr<T> Blob<T>::end()
{return BlobPtr<T>(*this,data->size());
}
template <typename T> inline void Blob<T>::check(size_type i,const std::string &msg) const
{if(i>=data->size())throw std::out_of_range(msg);
}
template <typename T> bool operator==(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data==*rhs.data;
}
template <typename T> bool operator!=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data<*rhs.data;
}
template <typename T> bool operator<=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data>*rhs.data;
}
template <typename T> bool operator>=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs<rhs);
}
//BlobPtr
template <typename T> std::shared_ptr<std::vector<T>> BlobPtr<T>::check(size_type i,const std::string &msg) const
{auto ret=wptr.lock();if(!ret)throw std::runtime_error("unbound BlobPtr");if(i>=ret->size())throw std::out_of_range(msg);return ret;
}
template <typename T> T & BlobPtr<T>::operator[](size_type i)
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> const T & BlobPtr<T>::operator[](size_type i) const
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++()
{check(curr,"increment past end of BlobPtr");++curr;return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++(int)
{BlobPtr ret=*this;++*this;return ret;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--()
{--curr;check(curr,"decrement past the begin of BlobPtr");return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--(int)
{BlobPtr ret=*this;--*this;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+(size_type i) const
{BlobPtr ret(*this);ret+=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-(size_type i) const
{BlobPtr ret(*this);ret-=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+=(size_type i) const
{check(curr+i,"increment past end of range");while(--i)++*this;return *this;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-=(size_type i) const
{check(curr-i,"decrement past begin of range");while(--i)--*this;return *this;
}
template <typename T> T & BlobPtr<T>::operator*() const
{auto p=check(curr,"dereference past end");return (*p)[curr];
}
template <typename T> T * BlobPtr<T>::operator->() const
{return & this->operator*();
}
template <typename T> bool operator==(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r)return (!r||lhs.curr==rhs.curr);elsereturn false;
}
template <typename T> bool operator!=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r&&l)return lhs.curr<rhs.curr;elsereturn false;
}
template <typename T> bool operator<=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return rhs<lhs;
}
template <typename T> bool operator>=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs<rhs);
}
#endif

18.8

#ifndef BLOB_H
#define BLOB_H
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <string>
#include <initializer_list>
#include <stdexcept>
template <typename> class BlobPtr;
template <typename> class Blob;
//Blob
template <typename T> bool operator==(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator!=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>=(const Blob<T> &,const Blob<T> &);
template <typename T> class Blob
{friend class BlobPtr<T>;friend bool operator==<T>(const Blob<T> &,const Blob<T> &);friend bool operator!=<T>(const Blob<T> &,const Blob<T> &);friend bool operator< <T>(const Blob<T> &,const Blob<T> &);friend bool operator<= <T>(const Blob<T> &,const Blob<T> &);friend bool operator> <T>(const Blob<T> &,const Blob<T> &);friend bool operator>= <T>(const Blob<T> &,const Blob<T> &);public:typedef T value_type;typedef typename std::vector<T>::size_type size_type;Blob() noexcept(false) try:data(std::make_shared<std::vector<T>>()){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(std::initializer_list<T> il) noexcept(false) try:data(std::make_shared<std::vector<T>>(il)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(const Blob &org) noexcept(false) try:data(std::make_shared<std::vector<T>>(*org.data)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}template <typename it> Blob(it b,it e) noexcept(false) try:data(std::make_shared<std::vector<T>>(b,e)) {} catch(std::bad_alloc &ba){std::cout<<ba.what()<<std::endl;}Blob &operator=(const Blob &);T & operator[](size_type i);const T & operator[](size_type i) const;size_type size() const {return data->size();}bool empty() const {return data->empty;}void push_back(const T &t){data->push_back(t);}void push_back(T &&t){data->push_back(std::move(t));}void pop_back();T & front();T & back();const T & front() const;const T & back() const;BlobPtr<T> begin();BlobPtr<T> end();~Blob() noexcept {};private:std::shared_ptr<std::vector<T>> data;void check(size_type i,const std::string &msg) const;
};
//BlobPtr
template <typename T> bool operator==(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator!=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> class BlobPtr
{friend bool operator==<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator!=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator< <T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator<=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator><T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator>=<T>(const BlobPtr<T> &,const BlobPtr<T> &);public:typedef typename std::vector<T>::size_type size_type;BlobPtr():curr(0){}BlobPtr(const Blob<T> &blob,size_type sz=0):wptr(blob.data),curr(sz){}T & operator[](size_type i);const T & operator[](size_type i) const;BlobPtr & operator++();BlobPtr & operator++(int);BlobPtr & operator--();BlobPtr & operator--(int);BlobPtr operator+(size_type) const;BlobPtr operator-(size_type) const;BlobPtr operator+=(size_type) const;BlobPtr operator-=(size_type) const;T & operator*() const;T * operator->() const;private:std::shared_ptr<std::vector<T>> check(size_type i,const std::string &msg) const;std::weak_ptr<std::vector<T>> wptr;size_type curr=0;
};
//Blob
template <typename T> Blob<T> & Blob<T>::operator=(const Blob &rhs)
{data=std::make_shared<std::vector<T>>(*rhs.data);return *this;
}
template <typename T> T & Blob<T>::operator[](size_type i)
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> const T & Blob<T>::operator[](size_type i) const
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> void Blob<T>::pop_back()
{check(0,"pop_back on empty Blob");data->pop_back();
}
template <typename T> T & Blob<T>::front()
{check(0,"front on empty Blob");return data->front();
}
template <typename T> const T & Blob<T>::front() const
{check(0,"front on empty Blob");return data->front();
}
template <typename T> T & Blob<T>::back()
{check(0,"back on empty Blob");return data->back();
}
template <typename T> const T & Blob<T>::back() const
{check(0,"back on empty Blob");return data->back();
}
template <typename T> BlobPtr<T> Blob<T>::begin()
{return BlobPtr<T>(*this);
}
template <typename T> BlobPtr<T> Blob<T>::end()
{return BlobPtr<T>(*this,data->size());
}
template <typename T> inline void Blob<T>::check(size_type i,const std::string &msg) const
{if(i>=data->size())throw std::out_of_range(msg);
}
template <typename T> bool operator==(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data==*rhs.data;
}
template <typename T> bool operator!=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data<*rhs.data;
}
template <typename T> bool operator<=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data>*rhs.data;
}
template <typename T> bool operator>=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs<rhs);
}
//BlobPtr
template <typename T> std::shared_ptr<std::vector<T>> BlobPtr<T>::check(size_type i,const std::string &msg) const
{auto ret=wptr.lock();if(!ret)throw std::runtime_error("unbound BlobPtr");if(i>=ret->size())throw std::out_of_range(msg);return ret;
}
template <typename T> T & BlobPtr<T>::operator[](size_type i)
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> const T & BlobPtr<T>::operator[](size_type i) const
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++()
{check(curr,"increment past end of BlobPtr");++curr;return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++(int)
{BlobPtr ret=*this;++*this;return ret;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--()
{--curr;check(curr,"decrement past the begin of BlobPtr");return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--(int)
{BlobPtr ret=*this;--*this;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+(size_type i) const
{BlobPtr ret(*this);ret+=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-(size_type i) const
{BlobPtr ret(*this);ret-=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+=(size_type i) const
{check(curr+i,"increment past end of range");while(--i)++*this;return *this;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-=(size_type i) const
{check(curr-i,"decrement past begin of range");while(--i)--*this;return *this;
}
template <typename T> T & BlobPtr<T>::operator*() const
{auto p=check(curr,"dereference past end");return (*p)[curr];
}
template <typename T> T * BlobPtr<T>::operator->() const
{return & this->operator*();
}
template <typename T> bool operator==(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r)return (!r||lhs.curr==rhs.curr);elsereturn false;
}
template <typename T> bool operator!=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r&&l)return lhs.curr<rhs.curr;elsereturn false;
}
template <typename T> bool operator<=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return rhs<lhs;
}
template <typename T> bool operator>=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs<rhs);
}
#endif

18.9

Sales_data.h

#include <iostream>
#include <string>
#include <stdexcept>
class isbn_mismatch: public std::logic_error
{
public:explicit isbn_mismatch(const std::string &s):std::logic_error(s) {}isbn_mismatch(const std::string &s,const std::string &lhs,const std::string &rhs):std::logic_error(s),left(lhs),right(rhs) {}const std::string left,right;
};
class Sales_data
{friend std::istream & operator>>(std::istream &,Sales_data &);friend std::ostream & operator<<(std::ostream &,const Sales_data &);friend Sales_data operator+(const Sales_data &,const Sales_data &);public:std::string isbn() const {return bookNo;}Sales_data()=default;Sales_data(const std::string &s):bookNo(s) {}Sales_data(const std::string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(n*p) {}Sales_data & operator+=(const Sales_data &);operator std::string() const {return bookNo;}operator double() const {return revenue;}private:std::string bookNo;unsigned units_sold=0;double revenue=0.0;double avg_price() const;
};
std::istream & operator>>(std::istream &,Sales_data &);
std::ostream & operator<<(std::ostream &,const Sales_data &);
Sales_data operator+(const Sales_data &,const Sales_data &);
bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs);

Sales_data.cpp

#include "Sales_data.h"
inline double Sales_data::avg_price() const
{if(units_sold)return revenue/units_sold;elsereturn 0;
}
std::istream & operator>>(std::istream &is,Sales_data &src)
{double price=0.0;is>>src.bookNo>>src.units_sold>>price;if(is)src.revenue=src.units_sold*price;elsesrc=Sales_data();return is;
}
std::ostream & operator<<(std::ostream &os,const Sales_data &src)
{os<<src.isbn()<<" "<<src.units_sold<<" "<<src.revenue<<" "<<src.avg_price();return os;
}
Sales_data & Sales_data::operator+=(const Sales_data & rhs)
{*this=*(this)+rhs;return *this;
}
Sales_data operator+(const Sales_data &lhs,const Sales_data &rhs)
{Sales_data tmp;if(lhs.isbn()!=rhs.isbn())throw isbn_mismatch("wrong isbns!",lhs.isbn(),rhs.isbn());tmp.bookNo=lhs.bookNo;tmp.units_sold=lhs.units_sold+rhs.units_sold;tmp.revenue=lhs.revenue+rhs.revenue;return tmp;
}
bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs)
{return lhs.isbn()<rhs.isbn();
}

test1.cpp

#include <iostream>
#include "Sales_data.h"
int main(void)
{Sales_data a("111",2,30),b("112",3,50);a+b;return  0;
}

不处理异常的输出
terminate called after throwing an instance of ‘isbn_mismatch’
what(): wrong isbns!
Aborted
test2.cpp

#include <iostream>
#include "Sales_data.h"
int main(void)
{Sales_data a("111",2,30),b("112",3,50);try{a+b;}catch(const isbn_mismatch &e){std::cerr<<e.what()<<": left isbn ("<<e.left<<") right isbn ("<<e.right<<")"<<std::endl;}return  0;
}

处理异常的输出
wrong isbns!: left isbn (111) right isbn (112)

18.10

见18.9

18.11

 如果what函数抛出异常的话,没有对应的catch子句捕获处理,就会调用terminate使程序结束,破坏正常逻辑。

18.12

Query.h

#ifndef _QUERY_H
#define _QUERY_H
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <fstream>
namespace chapter15
{class QueryResult;class TextQuery{public:using line_no=std::vector<std::string>::size_type;TextQuery(std::ifstream &);QueryResult query(const std::string &) const;private:std::shared_ptr<std::vector<std::string>> file;std::map<std::string,std::shared_ptr<std::set<line_no>>> wm;};class QueryResult{friend std::ostream &print(std::ostream &,const QueryResult &);public:QueryResult(std::string s,std::shared_ptr<std::set<std::vector<std::string>::size_type>> l,std::shared_ptr<std::vector<std::string>> f):sought(s),lines(l),file(f){}std::set<std::vector<std::string>::size_type>::iterator begin() const {return lines->begin();}std::set<std::vector<std::string>::size_type>::iterator end() const {return lines->end();}std::shared_ptr<std::vector<std::string>> get_file(){return file;}private:std::string sought;std::shared_ptr<std::set<std::vector<std::string>::size_type>> lines;std::shared_ptr<std::vector<std::string>> file;};std::ostream &print(std::ostream &,const QueryResult &);inline std::string make_plural(std::size_t count,const std::string &word,const std::string &ending){return (count>1)?word+ending:word;}class Query_base{friend class Query;protected:using line_no=TextQuery::line_no;virtual ~Query_base()=default;private:virtual QueryResult eval(const TextQuery &) const=0;virtual std::string rep() const=0;};class Query{friend Query operator~(const Query &);friend Query operator&(const Query &,const Query &);friend Query operator|(const Query &,const Query &);public:Query(const std::string &);QueryResult eval(const TextQuery &t) const {return q->eval(t);}std::string rep() const {return q->rep();}private:Query(std::shared_ptr<Query_base> query):q(query) {}std::shared_ptr<Query_base> q;};class WordQuery:public Query_base{friend class Query;private:WordQuery(const std::string &s):query_word(s) {}virtual QueryResult eval(const TextQuery &t) const {return t.query(query_word);}virtual std::string rep() const {return query_word;}std::string query_word;};inline Query::Query(const std::string &s):q(new WordQuery(s)) {}class NotQuery:public Query_base{friend Query operator~(const Query &);private:NotQuery(const Query &q):query(q) {}virtual QueryResult eval(const TextQuery &) const;virtual std::string rep() const {return "~("+query.rep()+")";}Query query;};inline Query operator~(const Query &q) {return std::shared_ptr<Query_base>(new NotQuery(q));}class BinaryQuery:public Query_base{protected:BinaryQuery(const Query &left,const Query &right,const std::string &s):lhs(left),rhs(right),opSym(s) {}virtual std::string rep() const {return "("+lhs.rep()+" "+opSym+" "+rhs.rep()+")";}Query lhs,rhs;std::string opSym;};class AndQuery:public BinaryQuery{friend Query operator&(const Query&,const Query&);private:AndQuery(const Query &left,const Query &right):BinaryQuery(left,right,"&") {}virtual QueryResult eval(const TextQuery &) const;};inline Query operator&(const Query &left,const Query &right) {return std::shared_ptr<Query_base>(new AndQuery(left,right));}class OrQuery:public BinaryQuery{friend Query operator|(const Query &,const Query &);private:OrQuery(const Query &left,const Query &right):BinaryQuery(left,right,"|") {}virtual QueryResult eval(const TextQuery &) const;};inline Query operator|(const Query &left,const Query &right) {return std::shared_ptr<Query_base>(new OrQuery(left,right));}inline std::ostream & operator<<(std::ostream &os,const Query &q) {return os<<q.rep();}
}
#endif

Query.cpp

#include <sstream>
#include <algorithm>
#include <cctype>
#include "Query.h"
namespace chapter15
{TextQuery::TextQuery(std::ifstream &infile):file(new std::vector<std::string>){std::string text;while(getline(infile,text)){file->push_back(text);std::size_t line_number=file->size()-1;std::istringstream line(text);std::string word;while(line>>word){std::string key_word;for(auto c:word){if(!ispunct(c))key_word+=c;}std::shared_ptr<std::set<line_no>> &lines=wm[key_word];if(!lines)lines.reset(new std::set<line_no>);lines->insert(line_number);}}}QueryResult TextQuery::query(const std::string &sought) const{static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>);std::map<std::string,std::shared_ptr<std::set<line_no>>>::const_iterator map_it=wm.find(sought);if(map_it==wm.end())return QueryResult(sought,nodata,file);elsereturn QueryResult(sought,map_it->second,file);}std::ostream &print(std::ostream &os,const QueryResult &qr){os<<"Executing Query for: "<<qr.sought<<std::endl;os<<qr.sought<<" occurs "<<qr.lines->size()<<" "<<make_plural(qr.lines->size(),"time","s")<<std::endl;for(auto num:*(qr.lines))os<<"\t(line "<<num+1<<") "<<*(qr.file->begin()+num)<<std::endl;return os;}QueryResult NotQuery::eval(const TextQuery &text) const{auto result=query.eval(text);auto beg=result.begin(),end=result.end();auto ret_lines=std::make_shared<std::set<line_no>>();auto sz=result.get_file()->size();for(std::size_t n=0;n!=sz;++n){if(beg==end||*beg!=n)ret_lines->insert(n);else if(beg!=end)++beg;}return QueryResult(rep(),ret_lines,result.get_file());}QueryResult OrQuery::eval(const TextQuery &text) const{auto left=lhs.eval(text),right=rhs.eval(text);auto ret_lines=std::make_shared<std::set<line_no>>(left.begin(),left.end());ret_lines->insert(right.begin(),right.end());return QueryResult(rep(),ret_lines,left.get_file());}QueryResult AndQuery::eval(const TextQuery &text) const{auto left=lhs.eval(text),right=rhs.eval(text);auto ret_lines=std::make_shared<std::set<line_no>>();set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*ret_lines,ret_lines->begin()));return QueryResult(rep(),ret_lines,left.get_file());}
}

TextQuery.h

#ifndef TEXT_QUERY_H
#define TEXT_QUERY_H
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <fstream>
#include <tuple>
namespace chapter10
{class TextQuery{public:using line_no=std::vector<std::string>::size_type;TextQuery(std::ifstream &);std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> query(const std::string &) const;private:std::shared_ptr<std::vector<std::string>> file;std::map<std::string,std::shared_ptr<std::set<line_no>>> wm;};inline std::string make_plural(std::size_t count,const std::string &word,const std::string &ending){return (count>1)?word+ending:word;}std::ostream &print(std::ostream &,const std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> &);
}
#endif

TextQuery.cpp

#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>
#include <memory>
#include "TextQuery.h"
using namespace std;
namespace chapter10
{TextQuery::TextQuery(ifstream &infile):file(new vector<string>){string text;while(getline(infile,text)){file->push_back(text);size_t line_number=file->size()-1;istringstream line(text);string word;while(line>>word){shared_ptr<set<line_no>> &lines=wm[word];if(!lines)lines.reset(new set<line_no>);lines->insert(line_number);}}}std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> TextQuery::query(const string &sought) const{static shared_ptr<set<line_no>> nodata(new set<line_no>);map<string,shared_ptr<set<line_no>>>::const_iterator map_it=wm.find(sought);if(map_it==wm.end())return tuple(sought,nodata,file);elsereturn tuple(sought,map_it->second,file);}std::ostream &print(std::ostream &os,const std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> &tp){os<<std::get<0>(tp)<<" occurs "<<std::get<1>(tp)->size()<<" "<<make_plural(std::get<1>(tp)->size(),"time","s")<<std::endl;for(auto num:*(get<1>(tp)))os<<"\t(line "<<num+1<<")"<<*(get<2>(tp)->begin()+num)<<std::endl;return os;}
}

test.cpp

#include <fstream>
#include "Query.h"
using namespace std;
using chapter15::Query;
using chapter15::TextQuery;
int main(int argc,char *argv[])
{ifstream infile(argv[1]);TextQuery text(infile);Query q=Query("fiery")&Query("bird")|Query("wind");print(cout,q.eval(text));return 0;
}

18.13

 需要使用文件作用域或者命名空间作用域的静态变量时可以使用未命名的命名空间。

18.14

mathLib::MatrixLib::matrix mathLib::MatrixLib::operator*(const matrix &,const matrix &);

18.15

using声明:一次只引入命名空间的一个成员,它的有效范围从using声明的地方开始,到using声音所在作用域结束为止。
using指示:使特定的命名空间中所有的名字都可见,这些名字一般被看作是出现在最近的外层作用域中,如果遇到成员冲突的情况,需要使用作用域运算符指明所需的版本。

18.16

位置一
using声明

ivar成员冲突

位置二
using声明

dvar成员冲突

位置一
using指示

++ivar这句将有二义性错误

位置二
using指示

++ivar这句将有二义性错误

18.17

1

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
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(void)
{return 0;
}

2

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
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(void)
{return 0;
}

3

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
int ivar=0;using namespace Exercise;void manip()
{double dvar=3.1416;int iobj=limit+1;++ivar;++::ivar;
}
int main(void)
{return 0;
}

4

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
int ivar=0;void manip()
{using namespace Exercise;double dvar=3.1416;int iobj=limit+1;++ivar;++::ivar;
}
int main(void)
{return 0;
}

18.18

 当mem1是一个string时程序因为更特例化的原因,会调用string中定义的swap版本,而int是内置类型,内置类型没有特定版本的swap,所以会调用std::swap。

18.19

 如果使用std::swap的形式,则是直接指明调用std命名空间中的swap版本。

18.20

  • 命名空间primerLib中声明的compte将被加入候选函数集
    候选函数void compute() void compute(const void *) void compute(int) void compute(double,double=3.4) void compute(char*,char*=0)
    可行函数
    void compute(const void *)0能转换成任意指针类型
    void compute(int)精确匹配
    void compute(double,double=3.4)int向double的算术类型转换
    void compute(char*,char*=0)0能转换成任意指针类型
  • 如果将using声明置于f函数中compute的调用点之前,将隐藏全局作用域中声明的compute.
    候选函数void compute() void compute(const void *)
    可行函数
    void compute(const void *)0能转换成任意指针类型

18.21

1 正确,public继承CAD,private继承Vehicle
2 错误,在一个派生列表中重复继承了同一个基类
3 正确,public继承istream,public继承ostream

18.22

 构造函数的执行顺序是A->B->C->X->Y->Z->MI

18.23

都允许

18.24

ZooAnimal *pz=new Panda("ying_yang")
pb->print();//调用Panda::print()
pb->cuddle();//错误,不属于ZooAnimal的接口
pb->highlight();//错误,不属于ZooAnimal的接口
delete->pb;//正确,Panda::~Panda()

18.25

  1. MI::print()
  2. MI::print()
  3. MI::print()
  4. MI::~MI()
  5. MI::~MI()
  6. MI::~MI()

18.26

 因为派生类的名字将隐藏基类的同名成员,所以MI不加前缀限定符的print函数只有接受std::vector参数的版本,而42无法隐式转换为该类型,所以调用失败。
可以这样修改:

struct MI:public Derived,public Base2
{void print(std::vector<double>);void print(int i){Base1::print(i);}protected:int *ival;std::vector<double> dvec;
}

18.26

  1. 所有可见的名字:
函数内:int dval;double cval;
类内:int *ival;std::vector<double> dvec;void print(std::vector<double>);
Derived:void Derived::print(std::string) const;std::string sval;double Derived::dval;
Base1:void Base1::print(int) const;int Base1::ival;double Base1::dval;char Base1::cval;
Base2:void Base2::print(double) const;int Base2::ival;double fval;char Base2::cval;
全局作用域:int ival;double dval;
dval    cval    ival    print都是继承自多个基类。
dval:Derived::dval  Base1::dval
cval:Base1::cval    Base2::cval
ival:Base1::ival    Base2::ival
print:Derived::print    Base1::print    Base2::print
void MI::foo(double cval)
{int dval;dval=Base1::dval+Derived::dval;
}
void MI::foo(double cval)
{int dval;Base2::fval=dvec.back();
}
void MI::foo(double cval)
{int dval;sval[0]=Base1::cval;
}

18.28

无需前缀限定符:
    Derived1::bar
     Derived2::ival
需要前缀限定符:
     Derived1::foo
     Derived2::foo
     Base::bar
     Base::ival
     Derived1::cval
     Derived2::cval

18.29

构造函数顺序:Class() Base() D1() D2() MI() Class() Final()
析构函数顺序:Final() Class() MI() D2() D1() Base() Class()
2. 1个base部分,两个Class部分。
3.
pb=new Class错误,不存在基类指针向派生类的隐式转换
pc=new Final错误,Class接口的使用会导致二义性错误
pmi=pb错误,不存在基类指针向派生类的隐式转换
pd2=pmi正确

18.30

这样定义的话,由于存在歧义,直接基类Class在Final中无法访问
class Class{};
class Base:public Class
{public:Base()=default;Base(const Base &b):i(b.i) {}Base(const int &ri):i(ri) {}private:int i;
};
class D1:public virtual Base
{public:D1()=default;D1(const D1 &d):Base(d) {}D1(const int &ri):Base(ri) {}
};
class D2:public virtual Base
{public:D2()=default;D2(const D2 &d):Base(d) {}D2(const int &ri):Base(ri) {}
};
class MI:public D1,public D2
{public:MI()=default;MI(const MI &mi):Base(mi),D1(mi),D2(mi) {}MI(const int &ri):Base(ri),D1(ri),D2(ri) {}
};
class Final:public MI,public Class
{public:Final()=default;Final(const Final &fi):Base(fi),MI(fi),Class() {}Final(const int &ri):Base(ri),MI(ri),Class() {}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/730635.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

并查集(蓝桥杯 C++ 题目 代码 注解)

目录 介绍&#xff1a; 模板&#xff1a; 题目一&#xff08;合根植物&#xff09;&#xff1a; 代码&#xff1a; 题目二&#xff08;蓝桥幼儿园&#xff09;&#xff1a; 代码&#xff1a; 题目三&#xff08;小猪存钱罐&#xff09;&#xff1a; 代码&#xff1a; …

WebGL之使用着色器将颜色应用于 WebGL

在之前的展示中我们已经创建好了一个正方形&#xff0c;接下来我们要做的就是给它添加一抹色彩。添加颜色可以通过修改着色器来实现。 给顶点着色 在 WebGL 中&#xff0c;物体是由一系列顶点组成的&#xff0c;每一个顶点都有位置和颜色信息。在默认情况下&#xff0c;所有像…

异常-Exception

文章目录 异常-Exception常见的运行时异常NullPointerException&#xff08;空指针异常&#xff09;ArithmeticException&#xff08;数学运算异常&#xff09;ArrayIndexOutOfBoundsException&#xff08;数组下标越界异常&#xff09;ClassCastException&#xff08;类型转换…

Basis运维日常检查清单- Checklist

检查SYSTEM 是否正常GUI登入登入到系统检查所有应用服务器是否活动正常SM51检查所有SAP Instance服务器运行是否正常.检查工作进程进行SM50检查是否有运行时间很长Local ProcessSM66检查是否有运行时间很长Global Process检查陈旧锁定条目SM12在User ID栏输入*. 检查前期的锁列…

网络编程聊天室

客户端 #include <myhead.h> //创建结构体存储用户信息 struct User {char tape;char username[32];char msg[1024]; };int main(int argc, const char *argv[]) {//创建套接字与服务器进行通信int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){perror("socket err…

鸿蒙实战开发Camera组件:【相机】

相机组件支持相机业务的开发&#xff0c;开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发&#xff0c;最常见的操作如&#xff1a;预览、拍照和录像等。 基本概念 拍照 此功能用于拍摄采集照片。 预览 此功能用于在开启相机后&#xff0c;在缓冲区内重复采集…

django默认后台管理显示内容深化设置

1、设置models字段展示为只读模式 如某个字段在展示时不允许修改&#xff0c;可在admin.py的注册类下重写函数get_readonly_fields&#xff0c;例&#xff1a; def get_readonly_fields(self, request, objNone): return (dwdm,dwmc,"zjs","yyj"…

ARC-Challenge数据集分享

来源: AINLPer公众号&#xff08;每日干货分享&#xff01;&#xff01;&#xff09; 编辑: ShuYini 校稿: ShuYini 时间: 2024-2-28 该数据集由Allen Institute for Artificial Intelligence&#xff08;AI2&#xff09;发布&#xff0c;旨在推动高级问答的研究。该数据集包含…

#微信小程序(按键控制)

1.IDE&#xff1a;微信开发者工具 2.实验&#xff1a;微信小程序设计两个按钮&#xff0c;对onenet平台数据流&#xff08;旧版&#xff09;来进行http post上传&#xff0c;下位机再http get得到控制信息 3.记录 &#xff08;1&#xff09;bind-tap&#xff08;绑定函数&…

3D数字孪生运行不起来?该检查你的电脑配置了

运行3D数字孪生项目通常需要一定的计算资源和图形处理能力。以下是一些常见的电脑配置要求&#xff0c;可以作为参考&#xff1a;1处理器&#xff08;CPU&#xff09;&#xff1a;推荐使用多核心处理器&#xff0c;如Intel Core i7或更高级别的处理器。较高的时钟频率和较大的缓…

Linux shell 网络掩码地址转CIDR

例子&#xff1a; ./1.sh 255.255.255.0 ./1.sh 255.255.255.128 ./1.sh 255.255.0.0 源实现&#xff1a; #!/bin/bashnetmask_to_cidr() {local IFSlocal -a octetslocal i0local cidr0IFS. read -r -a octets <<< "$1"for octet in "${octets[]}…

Sora关于视频分镜的提示词技巧

视频分镜是视频制作中至关重要的一环&#xff0c;它决定了视频内容的结构、节奏和视觉效果。在Sora文生视频模型中&#xff0c;通过巧妙地运用提示词&#xff0c;你可以更加高效地进行视频分镜设计&#xff0c;提升视频的质量和观众体验。以下是10个关于视频分镜的提示词技巧&a…

kafka报文模拟工具的使用

日常项目中经常会碰到消费kafka某个topic的数据&#xff0c;如果知道报文格式&#xff0c;即可使用工具去模拟发送报文&#xff0c;以此测试代码中是否能正常消费到这个数据。 工具资源已上传&#xff0c;可直接访问连接下载&#xff1a;https://download.csdn.net/download/w…

CSS补充(下),弹性布局(上)

高级选择器 1.兄弟选择器 2.同时满足 div.bg{background-color: red;}p.bg{background-color: green;}spam.bg{background-color: blue;}注&#xff1a;选择器中间没有空格&#xff0c;有明确标识的选择器写在后面 3.各种伪类的应用 3.1作为第几个子元素 选择器:nth-child…

React-父传子

1.概念 说明&#xff1a;父组件传递数据子组件标签身上绑定属性&#xff1b;子组件接受数据props的参数。props是一个对象&#xff0c;包含父组件传递的所有数据。例如数字、字符串、布尔值、数组、对象、函数、JSX。不允许直接修改父组件传递的数据。 2.例子 // 父传子 // …

uniapp踩坑之项目:uni.previewImage简易版预览单图片

主要使用uni.previewImage //html <view class"box-card" v-for"(item,index) in DataList" :key"index"><view>图片&#xff1a;</view><image :src"item.Path" tap.stop"clickImg(item.Path)">&l…

有点NB的免费wordpress主题模板

一个不错的黄色模板&#xff0c;用WP免费主题模板搭建家政服务公司网站。 https://www.wpniu.com/themes/15.html

【性能】JDK和Jmeter的安装与配置

一、JDK环境配置 1. 下载JDK 官网下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html 选择对应系统的安装包&#xff0c;下载后安装&#xff0c;安装中记录JDK安装的地址&#xff0c;之后一直点击下一…

继深圳后,重庆与鸿蒙展开原生应用开发合作

截至2023年底&#xff0c;开源鸿蒙开源社区已有250多家生态伙伴加入&#xff0c;开源鸿蒙项目捐赠人达35家&#xff0c;通过开源鸿蒙兼容性测评的伙伴达173个&#xff0c;累计落地230余款商用设备&#xff0c;涵盖金融、教育、智能家居、交通、数字政府、工业、医疗等各领域。 …

【Python】科研代码学习:三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer

【Python】科研代码学习&#xff1a;三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer 前言Models : PreTrainedModelPreTrainedModel 中重要的方法 tensorflow & pytorch 简单对比Configuration : PretrainedConfigPretrainedConfig 中重要的方法 Tokenizer : …