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

2024-03-09 02:12

本文主要是介绍c++ primer中文版第五版作业第十九章,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

仓库地址

文章目录

      • 19.1
      • 19.2
      • 19.3
      • 19.4
      • 19.5
      • 19.6
      • 19.7
      • 19.8
      • 19.9
      • 19.10
      • 19.11
      • 19.12
      • 19.13
      • 19.14
      • 19.15
      • 19.16
      • 19.17
      • 19.18
      • 19.20
      • 19.21
      • 19.22
      • 19.23
      • 19.24
      • 19.25
      • 19.26

19.1

#include <cstdlib>
#include <memory>
using std::bad_alloc;
void * operator new(size_t size)
{if(void *result=malloc(size))return result;elsethrow bad_alloc();
}
void operator delete(void *mem) noexcept
{free(mem);
}

19.2

StrVec.h

#ifndef _STRVEC_H
#define _STRVEC_H
#include <string>
#include <cstddef>
#include <utility>
#include <memory>
#include <initializer_list>
void *operator new(size_t);
void operator delete(void *) noexcept;
class StrVec
{public:StrVec():elements(nullptr),first_free(nullptr),cap(nullptr) {}StrVec(const StrVec &);StrVec(StrVec &&s) noexcept :elements(s.elements),first_free(s.first_free),cap(s.cap) {s.elements=s.first_free=s.cap=nullptr;}StrVec(std::initializer_list<std::string>);StrVec & operator=(const StrVec &);StrVec & operator=(StrVec &&) noexcept;~StrVec() {free();}void push_back(const std::string &);void push_back(std::string &&);size_t size() {return first_free-elements;}size_t capacity() {return cap-elements;}std::string *begin() const {return elements;}std::string *end() const {return first_free;}void resize(const size_t n,const std::string &orgv=std::string());void reserve(const size_t n);private:std::string *elements;std::string *first_free;std::string *cap;static std::allocator<std::string> alloc;void chk_n_alloc() {if(size()==capacity()) reallocate();}std::pair<std::string *,std::string *> alloc_n_copy(const std::string *,const std::string *);void free();void reallocate();
};
#endif

StrVec.cpp

#include "StrVec.h"
#include <cstdlib>
#include <memory>
std::allocator<std::string> StrVec::alloc;
StrVec::StrVec(const StrVec &org)
{std::pair<std::string *,std::string *> data=alloc_n_copy(org.begin(),org.end());elements=data.first;first_free=cap=data.second;
}
StrVec::StrVec(std::initializer_list<std::string> ls)
{auto data=alloc_n_copy(ls.begin(),ls.end());elements=data.first;first_free=cap=data.second;
}
StrVec & StrVec::operator=(const StrVec &rhs)
{auto data=alloc_n_copy(rhs.begin(),rhs.end());free();elements=data.first;first_free=cap=data.second;return *this;
}
StrVec & StrVec::operator=(StrVec &&s) noexcept
{if(this!=&s){free();elements=s.elements;first_free=s.first_free;cap=s.cap;s.elements=s.first_free=s.cap=nullptr;}return *this;
}
void StrVec::push_back(const std::string &s)
{chk_n_alloc();alloc.construct(first_free++,s);
}
void StrVec::push_back(std::string &&s)
{chk_n_alloc();alloc.construct(first_free++,std::move(s));
}
std::pair<std::string *,std::string *> StrVec::alloc_n_copy(const std::string *b,const std::string *e)
{std::string *data=alloc.allocate(e-b);return {data,uninitialized_copy(b,e,data)};
}
void StrVec::free()
{if(elements){for(auto p=first_free;p!=elements;)alloc.destroy(--p);alloc.deallocate(elements,cap-elements);}
}
void StrVec::reallocate()
{size_t newcapacity=size()?2*size():1;std::string *newdata=alloc.allocate(newcapacity);std::string *dest=newdata;std::string *src=elements;for(size_t i=0;i!=size();++i)alloc.construct(dest++,std::move(*src++));free();elements=newdata;first_free=dest;cap=elements+newcapacity;
}
void StrVec::reserve(const size_t n)
{if(n>capacity()){std::string *newdata=alloc.allocate(n);std::string *dest=newdata;std::string *src=elements;for(size_t i=0;i!=size();++i)alloc.construct(dest++,std::move(*src++));free();elements=newdata;first_free=dest;cap=elements+n;}
}
void StrVec::resize(const size_t n,const std::string &orgv)
{if(n<=size()){std::string *b=elements+n;std::string *e=first_free;while(b!=e)alloc.destroy(b++);first_free=elements+n;}else if(n<=capacity()){std::string *b=first_free;std::string *e=elements+n;while(b!=e)alloc.construct(b++,orgv);first_free=e;}else{reserve(n);std::string *b=first_free;std::string *e=elements+n;while(b!=e)alloc.construct(b++,orgv);first_free=e;}
}
void * operator new(size_t size)
{if(void *result=malloc(size))return result;elsethrow std::bad_alloc();
}
void operator delete(void *mem) noexcept
{free(mem);
}

19.3

1 成功,因为pa的类型是目标类型的公有基类。
2 失败,因为pb实际指向B类型而非目标C类型。
3 失败,因为A是D的一个二义基类。

#include <iostream>
#include <memory>
class A
{public:A()=default;virtual ~A()=default;
};
class B:public A
{public:B()=default;virtual ~B()=default;
};
class C:public B
{public:C()=default;virtual ~C()=default;
};
class D:public B,public A
{public:D()=default;virtual  ~D()=default;
};
int main(void)
{
//	A *pa=new C;
//	B *pb=dynamic_cast<B *>(pa);B *pb=new B;if(C *pc=dynamic_cast<C *>(pb))std::cout<<"yes"<<std::endl;elsestd::cout<<"no"<<std::endl;
//	A *pa=new D;
//	B *pb=dynamic_cast<B *>(pa);return 0;
}

19.4

#include <iostream>
#include <memory>
class A
{public:A()=default;virtual ~A()=default;
};
class B:public A
{public:B()=default;virtual ~B()=default;
};
class C:public B
{public:C()=default;virtual ~C()=default;
};
class D:public B,public A
{public:D()=default;virtual  ~D()=default;
};
int main(void)
{
//运行时会抛出错误A *pa=new A;try{C &rc=dynamic_cast<C &>(*pa);}catch(std::bad_cast err){std::cerr<<err.what()<<std::endl;}return 0;
}

19.5

 想要使用基类的引用或指针使用派生类的非虚函数操作的时候。

19.6

 这一节的三题用到的Query_base纯虚函数,AndQuery的构造函数是private的,所以无法构造它们的对象,只能改了改Query.h文件。
Query.h

#ifndef _QUERY_H
#define _QUERY_H
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <fstream>
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();}Query(std::shared_ptr<Query_base> query):q(query) {}private: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&);public: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

test1.cpp

#include <fstream>
#include <memory>
#include "Query.h"
using namespace std;
int main(int argc,char *argv[])
{Query a("bird");Query b("third");Query_base *bp=new AndQuery(a,b);if(AndQuery *ap=dynamic_cast<AndQuery *>(bp)){cout<<"translate successed."<<endl;}elsecout<<"translate failed."<<endl;return 0;
}

19.7

test2.cpp

#include <fstream>
#include <memory>
#include <typeinfo>
#include "Query.h"
using namespace std;
int main(int argc,char *argv[])
{Query a("bird");Query b("third");Query_base *bp=new AndQuery(a,b);try{dynamic_cast<AndQuery &>(*bp);cout<<"translate successed."<<endl;}catch(bad_cast){cout<<"translate failed."<<endl;}return 0;
}

19.8

test3.cpp

#include <fstream>
#include <memory>
#include <typeinfo>
#include "Query.h"
using namespace std;
int main(int argc,char *argv[])
{Query a("bird");Query b("third");Query_base *bp=new AndQuery(a,b);if(typeid(Query_base)==typeid(*bp))cout<<"It's Query_base class."<<endl;if(typeid(AndQuery)==typeid(*bp))cout<<"It's AndQuery class."<<endl;return 0;
}

19.9

#include <iostream>
#include <typeinfo>
#include <string>
#include "19-6/Query.h"
using std::cout;
using std::endl;
using std::string;
int main(void)
{int i;double d;char c;string str;Query q("hi");cout<<typeid(i).name()<<","<<typeid(d).name()<<","<<typeid(c).name()<<","<<typeid(str).name()<<","<<typeid(q).name()<<endl;return 0;
}

19.10

1 A *
2 A *
3 B

19.11

 指向数据成员的指针的类型除了成员的类型外,还应该包括类的类型。在使用数据成员指针时还需要 提供对象的信息。

19.12

Screen.h

#include <string>
class Screen
{public:using pos=std::string::size_type;Screen()=default;Screen(pos ht,pos wd):height{ht},width{wd},contents(ht*wd,' '){}Screen(pos ht,pos wd,char c):height{ht},width{wd},contents(ht*wd,c){}char get() const {return contents[cursor];}char get(pos r,pos c) const;Screen &move(pos r,pos c);Screen &set(char);Screen &set(pos,pos,char);Screen &display(std::ostream &os){do_display(os);return *this;}const Screen &display(std::ostream &os) const {do_display(os);return *this;}static pos Screen::* data(){return &Screen::cursor;}private:pos cursor=0,height=0,width=0;std::string contents;void  do_display(std::ostream &os) const {os<<contents;}
};
inline char Screen::get(pos r,pos c) const
{pos row=r*width;return contents[row+c];
}
inline Screen &Screen::move(pos r,pos c)
{pos row=r*width;cursor=row+c;return *this;
}
inline Screen &Screen::set(char ch)
{contents[cursor]=ch;return *this;
}
inline Screen &Screen::set(pos r,pos c,char ch)
{contents[r*width+c]=ch;return *this;
}

19-12.cpp

#include <iostream>
#include "Screen.h"
int main(void)
{Screen scr(5,6,'*');scr.move(2,3);auto pc=Screen::data();std::cout<<scr.*pc<<std::endl;return 0;
}

19.13

static const std::string Sales_data::* data(){return &Sales_data::bookNo;}

19.14

auto pmf=&Screen::get_cursor;合法,pmf是一个成员函数指针,它指向Screen类的常量成员函数,该函数不接受参数,返回一个char类型数据.
pmf=&Screen::get合法,pmf被赋值为Screen类内不接受参数并返回char类型值的那个get成员函数。

19.15

 指向成员函数的指针的类型包含所指向的类的类型,并且在调用时需要提供类的对象,同时指向成员函数的指针和成员函数名之间不存在自动转换规则。

19.16

using avp=double (Sales_data::*) () const

19.17

#include <string>
class Screen
{public:using pos=std::string::size_type;Screen()=default;Screen(pos ht,pos wd):height{ht},width{wd},contents(ht*wd,' '){}Screen(pos ht,pos wd,char c):height{ht},width{wd},contents(ht*wd,c){}char get() const {return contents[cursor];}char get(pos r,pos c) const;Screen &move(pos r,pos c);Screen &set(char);Screen &set(pos,pos,char);Screen &display(std::ostream &os){do_display(os);return *this;}const Screen &display(std::ostream &os) const {do_display(os);return *this;}static pos Screen::* data(){return &Screen::cursor;}private:pos cursor=0,height=0,width=0;std::string contents;void  do_display(std::ostream &os) const {os<<contents;}
};
/*在这里*/
using p1=char (Sales_data::*) () const;
using p2=char (Sales_data::*) (Screen::pos,Screen::pos) const;
using p3=Screen & (Sales_data::*) (Screen::pos,Screen::pos);
using p4=Screen & (Sales_data::*) (char);
using p5=Screen & (Sales_data::*) (Screen::pos,Screen::pos,char);
using p6=Screen & (Sales_data::*) (std::ostream &);
using p7=const Screen & (Sales_data::*) (std::ostream &) const;
using p8=void (Sales_data::*) (std::ostream &) const;
/********/
inline char Screen::get(pos r,pos c) const
{pos row=r*width;return contents[row+c];
}
inline Screen &Screen::move(pos r,pos c)
{pos row=r*width;cursor=row+c;return *this;
}
inline Screen &Screen::set(char ch)
{contents[cursor]=ch;return *this;
}
inline Screen &Screen::set(pos r,pos c,char ch)
{contents[r*width+c]=ch;return *this;
}

19.18

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using std::vector;
using std::string;
using std::cout;
using std::endl;
using std::placeholders::_1;
int main(void)
{vector<string> svec={"hi","","","hello",""};cout<<count_if(svec.begin(),svec.end(),bind(&string::empty,_1))<<endl;return 0;
}

19.20

19-20.cpp

#include <iostream>
#include <fstream>
#include "TextQuery.h"
using namespace std;
void runQueries(ifstream &infile)
{TextQuery tq(infile);while(true){cout<<"enter word to look for, or q to quit:";string s;if(!(cin>>s)||s=="q")break;print(cout,tq.query(s))<<endl;}
}
int main(int argc,char *argv[])
{ifstream infile(argv[1]);runQueries(infile);return 0;
}

TextQuery.h

#ifndef TEXT_QUERY_H
#define TEXT_QUERY_H
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <fstream>
#include <iostream>
#include <string>
class TextQuery
{
public:class QueryResult;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 TextQuery::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){}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 TextQuery::QueryResult &);
inline std::string make_plural(std::size_t count,const std::string &word,const std::string &ending)
{return (count>1)?word+ending:word;
}
#endif

TextQuery.cpp

#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>
#include <memory>
#include "TextQuery.h"
using namespace std;
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);}}
}
TextQuery::QueryResult 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 QueryResult(sought,nodata,file);elsereturn QueryResult(sought,map_it->second,file);
}std::ostream &print(std::ostream &os,const TextQuery::QueryResult &qr)
{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;
}

19.21

token.h

#ifndef TOKEN_H
#define TOKEN_H
#include <string>
#include <iostream>
#include "Sales_data.h"
using std::string;
class Token
{friend std::ostream & operator<<(std::ostream &,const Token &);public:Token():tok(INT),ival(0) {}Token(const Token &t):tok(t.tok) {copyUnion(t);}Token(Token &&t):tok(std::move(t.tok)) {moveUnion(std::move(t));}~Token(){if(tok==STR)sval.~string();else if(tok==SAL)salval.~Sales_data();}Token & operator=(const Token &);Token & operator=(Token &&);Token & operator=(const std::string &);Token & operator=(const Sales_data &);Token & operator=(int);Token & operator=(char);Token & operator=(double);private:enum {INT,CHAR,DBL,STR,SAL} tok;union{int ival;char cval;double dval;std::string sval;Sales_data salval;};void copyUnion(const Token &);void moveUnion(Token &&);void free(){if(tok==STR)sval.~string();if(tok==SAL)salval.~Sales_data();}
};
std::ostream & operator<<(std::ostream &,const Token &);
#endif

token.cpp

#include "token.h"
void Token::copyUnion(const Token &t)
{switch(tok){case Token::INT:ival=t.ival;break;case Token::CHAR:cval=t.cval;break;case Token::DBL:dval=t.dval;break;case Token::STR:new (&sval) std::string(t.sval);break;case Token::SAL:new (&salval) Sales_data(t.salval);break;}
}
void Token::moveUnion(Token &&t)
{switch(tok){case Token::INT:ival=t.ival;break;case Token::CHAR:cval=t.cval;break;case Token::DBL:dval=t.dval;break;case Token::STR:new (&sval) std::string(std::move(t.sval));break;case Token::SAL:new (&salval) Sales_data(std::move(t.salval));break;}
}
Token & Token::operator=(int i)
{if(tok==STR)sval.~string();if(tok==SAL)salval.~Sales_data();tok=INT;ival=i;return *this;
}
Token & Token::operator=(char ch)
{if(tok==STR)sval.~string();if(tok==SAL)salval.~Sales_data();tok=CHAR;cval=ch;return *this;
}
Token & Token::operator=(double d)
{if(tok==STR)sval.~string();if(tok==SAL)salval.~Sales_data();tok=DBL;dval=d;return *this;
}
Token & Token::operator=(const std::string &str)
{if(tok==STR)sval=str;else if(tok==SAL){salval.~Sales_data();tok=STR;new (&sval) std::string(str);}else{tok=STR;new (&sval) std::string(str);}return *this;
}
Token & Token::operator=(const Sales_data &sales)
{if(tok==SAL)salval=sales;else if(tok==STR){sval.~string();tok=SAL;new (&salval) Sales_data(sales);}else{tok=SAL;new (&salval) Sales_data(sales);}return *this;
}
Token & Token::operator=(const Token &t)
{switch(tok){case Token::STR:if(t.tok==STR)sval=t.sval;else{sval.~string();tok=t.tok;copyUnion(t);}	break;case Token::SAL:if(t.tok==SAL)salval=t.salval;else{salval.~Sales_data();tok=t.tok;copyUnion(t);}break;default:tok=t.tok;copyUnion(t);}return *this;
}
Token & Token::operator=(Token &&t)
{if(this!=&t){free();tok=std::move(t.tok);moveUnion(std::move(t));}return *this;
}
std::ostream & operator<<(std::ostream &os,const Token &t)
{switch(t.tok){case Token::INT:std::cout<<t.ival;break;case Token::CHAR:std::cout<<t.cval;break;case Token::DBL:std::cout<<t.dval;break;case Token::STR:std::cout<<t.sval;break;case Token::SAL:std::cout<<t.salval;break;}return os;
}

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;}double avg_price() const;private:std::string bookNo;unsigned units_sold=0;double revenue=0.0;
};
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();
}

19.22

见19.21

19.23

见19.21

19.24

不会出错

19.25

见19.21
test.cpp

#include <iostream>
#include <string>
#include "token.h"
int main(void)
{Token t;t=1;std::cout<<t<<std::endl;t='c';std::cout<<t<<std::endl;t=1.314;std::cout<<t<<std::endl;t="hello";std::cout<<t<<std::endl;t=Sales_data("10212x",3,24);std::cout<<t<<std::endl;return 0;
}

19.26

extern "C" int compute(int *,int);//这是一个C函数,它接受两个参数int *以及int,返回int
extern "C" double compute(double *,double);//这是一个C函数,它接受两个参数double *以及double,返回double

 不合法,因为C语言不支持函数重载,这两个函数的名字相同了。

这篇关于c++ primer中文版第五版作业第十九章的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/789244

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

C++中处理文本数据char与string的终极对比指南

《C++中处理文本数据char与string的终极对比指南》在C++编程中char和string是两种用于处理字符数据的类型,但它们在使用方式和功能上有显著的不同,:本文主要介绍C++中处理文本数... 目录1. 基本定义与本质2. 内存管理3. 操作与功能4. 性能特点5. 使用场景6. 相互转换核心区别

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c