C++ Primer 第五版 部分课后题答案

Posted YOYCod

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Primer 第五版 部分课后题答案相关的知识,希望对你有一定的参考价值。

            当时刚学C++的时候买了这本书,一开始前面看的一知半解,索性就先缓缓,等学完学校的C++课程(中途自己也写了不少c++的代码),一段时间之后又拿起这本书去看,感觉还是挺有滋味的,这本书对我印象中的C++做了很大的扩展,个人认为这本书不太适合刚学C++就去看,而是写了一定的代码,对C++有一个大体的了解之后再去看会很有味道。在看书的过程中自己也写了上面的课后练习题,现在整理一下,也跟大家分享一下,下面是9~12 15~16章的课后题编程题的答案

(第八章之前的都没保存/(ㄒoㄒ)/~~):

当时保存的时候是按节保存的,比如 练习9.3、练习9.4 练习9.5、练习9.6 是在9.2.1节练习里面的题

9.2.1节练习:

<span style="font-size:18px;">#include <iostream>
#include <vector>

std::vector<int>::iterator fun(std::vector<int>::iterator isb,std::vector<int>::iterator ise,int y){
    while(isb<ise)
        if(*(isb)==y)
            return isb;
        else  isb++;
    return ise;
}
int main()
{
    std::vector<int> s={1,2,3};
    std::vector<int>::iterator is=s.begin();
    //if(fun(is,s.end(),2)) cout<<"OK"<<endl;
    is=fun(is,s.end(),2);
    std::cout<<*is<<std::endl;
    while(std::cout<<*is<<"#" && (is++)<s.end());
    return 0;
}
</span>

9.3.1节练习:

#include <iostream>
#include <vector>
#include <list>
#include <deque>

int main()
{
    std::string temp;
    std::deque<std::string>dq;
    for(int i=1;i<=3;++i){
        std::cin>>temp;
        dq.push_front(temp);
    }
    auto x=dq.begin(); //std::deque<std::string>::iterator x;
    while(x < dq.end() && std::cout<<" "<<*(x++));
    std::cout<<std::endl;


    std::list<std::string>l;
    for(int i=1;i<=3;++i){
        std::cin>>temp;
        l.push_front(temp);
    }
    auto y=l.begin();
    while(y!=l.end() && std::cout<<" "<<*(y++)); //list中无 > <操作 使用!=代替
    std::cout<<std::endl;

    return 0;
}

9.3.3节练习:

#include <iostream>
#include <vector>
#include <list>
#include <deque>

int main()
{
    int ia[]={0,1,1,2,3,5,8,13,21,55,89};
    std::vector<int > vec={0,1,1,2,3,5,8,13,21,55,89};
    std::list<int > lis={0,1,1,2,3,5,8,13,21,55,89};

    auto i=vec.begin();
    while(i!=vec.end())
        if(*i % 2)i=vec.erase(i);
        else i++;

    auto j=lis.begin();
    while(j!=lis.end())
        if(*j % 2==0)j=lis.erase(j);
        else j++;

    for(auto x:vec) std::cout<<" "<<x;
    std::cout<<std::endl;
    for(auto x:lis) std::cout<<" "<<x;
    std::cout<<std::endl;
    return 0;
}

9.5.3节练习:

练习9.47:

#include <iostream>
#include <algorithm>


int main()
{
    std::string temp("ab2c3d7R4");
    std::string digit("0123456789");
    std::string word;
    for(int i=0;i<24;++i){
        word+=(char)('a'+i);
        word+=(char)('A'+i);
    }
    std::string::size_type pos=0;
    while((pos=temp.find_first_of(word,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;
    pos=0;
    while((pos=temp.find_first_of(digit,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;
    pos=0;
    while((pos=temp.find_first_not_of(digit,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;
    pos=0;
    while((pos=temp.find_first_not_of(word,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;
    return 0;
}

练习9.49:

#include <iostream>

int main()
{
    std::string temp("bdfghijklpqty");
    std::string s;
    while(std::cin>>s){
        std::string::size_type pos=0;
        while((pos=s.find_first_not_of(temp,pos))!=std::string::npos)std::cout<<s[pos++];
        std::cout<<std::endl;
    }
    return 0;
}

练习9.50:

#include <iostream>
#include <vector>

int main()
{
    std::vector<std::string > vec={"1","2","3","4","5"};
    int sum1=0;
    for(auto x:vec) sum1+=stoi(x);  //codeblock(12.11)报错,vs2012也报,本汪编译器不支持
    std::cout<<sum1<<std::endl;

    double sum2=0.0;
    for(auto x:vec) sum2+=stod(x);
    std::cout<<sum2<<std::endl;
    return 0;
}
练习9.51:

#include <iostream>

class A{
    public :
        A(const std::string s="10/12/1994"){
            std::string sign=" ,/";
            auto pos=s.find_first_of(sign);
            month=s.substr(0,pos);
            day=s.substr(pos+1,s.find_first_of(sign,pos+1)-pos-1);
            year=s.substr(s.find_last_of(sign)+1);
        }
        void print(){
            std::cout<<month<<" "<<day<<" "<<year<<std::endl;
        }
    private:
        std::string year,day,month;
};
int main()
{
    A a;
    a.print();
    A b("jan 1/1990");
    b.print();
    return 0;
}
/*

#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>
#include <numeric>
#include <cstring>

using namespace std;
int main()
{
    int a1[]={1,2,3,4,5,6};
    int a2[sizeof(a1)/sizeof(a1)];
    auto ret=copy(begin(a1),end(a1),begin(a2));

    return 0;
}

*/

练习10.1:

#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>

using namespace std;
int main()
{
    std::vector<int > vec={1,2,3,4,5,6,7,12,3,4,6,7,3,6,9,2,6,3,3,3,3,3,3};
    std::cout<<count(vec.begin(),vec.end(),3)<<std::endl;

    std::list<std::string > lis={"q","e","sdg","zvgs","123g","545","qwe","uyt","qwe"};
    std::cout<<count(lis.begin(),lis.end(),"qwe")<<std::endl;
    return 0;
}

10.2.1节练习:

/*
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>

using namespace std;

class A{
    public :
        A(const string s="1/1/1990"):month("jan"),day("1"),year("1994"){
            string sign=" ,/";
            auto pos=s.find_first_of(sign);
            month=s.substr(0,pos);
            day=s.substr(pos+1,s.find_first_of(sign,pos+1)-pos-1);
            year=s.substr(s.find_last_of(sign)+1);
        }
        void print(){
            cout<<month<<" "<<day<<" "<<year<<endl;
        }
    private:
        string year,day,month;
};
int main()
{
    A a();
    a.print();

   // A b("1/1/1990");
   // b.print();
    return 0;
}
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
int main()
{
    std::vector<int > vec={1,2,3,4,5,6,7,8,9};
    std::cout<<accumulate(vec.cbegin(),vec.cend(),0)<<std::endl;

    std::vector<std::string > vec_str={"a","b","c","d"};
    std::cout<<accumulate(vec_str.cbegin(),vec_str.cend(),std::string(""))<<std::endl;
    //accumulate(,,"");错误 const char* 没有定义+操作
    //accumulate(,,"hello"); 最后结果是 helloxxxx

    char *s=(char *)malloc(10*sizeof(char));
    char s1[]="heheda",s2[]="heheda";
    std::cout<<std::equal(s1,s1+strlen(s1),s2)<<std::endl;
    return 0;
}
10.2.2节练习:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>

int main()
{
//10.6
    int num[]={1,2,3,4,5,6};
    std::fill_n(std::begin(num),std::end(num)-std::begin(num),0);
    for(auto x:num) std::cout<<x<<" ";
    std::cout<<std::endl;

//10.7 a
    std::vector<int > vec;
    std::list<int >lst;
    int i;
    while(std::cin>>i) lst.push_back(i);
    std::copy(lst.cbegin(),lst.cend(),back_inserter(vec)); //vec未申请空间,所以使用插入迭代器
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;

//10.7 b
    std::vector<int > vecc;
    vecc.reserve(10);
    //虽然分配了内存 但size()=0 vecc.begin()==vecc.end() capacity()=10
    std::fill_n(vecc.begin(),10,0);
    for(auto x:vecc) std::cout<<x<<" ";
    std::cout<<std::endl;
    return 0;
}
10.2.3节练习:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>

void elimDups(std::vector<std::string > &vec){
    std::sort(vec.begin(),vec.end());
    auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器
    vec.erase(uni,vec.end());
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;
}
int main()
{
    std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};
    elimDups(vec);
    return 0;
}
// the quick red fox jumps over the slow red turtle
10.3.1节练习:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>

void elimDups(std::vector<std::string > &vec){
    std::sort(vec.begin(),vec.end());
    auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器
    vec.erase(uni,vec.end());
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;
}
bool isShortter(std::string a,std::string b){
    return a.size()<b.size();
}

bool islessfive(const std::string &a){
    return a.length()<5;
}

int main()
{
    std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};
    elimDups(vec);
    std::stable_sort(vec.begin(),vec.end(),isShortter);
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;

    auto iter=partition(vec.begin(),vec.end(),islessfive);
    while(iter!=vec.end())std::cout<<*iter++<<" ";
    std::cout<<std::endl;
    return 0;
}
// the quick red fox jumps over the slow red turtle

10.3.2节练习:

练习10.16:

#include <iostream>
#include <vector>
#include <algorithm>

void elimDups(std::vector<std::string > &vec){
    std::sort(vec.begin(),vec.end());
    auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器
    vec.erase(uni,vec.end());
    std::cout<<"after unique_sort and erase :"<<std::endl;
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;
}

int main()
{
    //10.15
    int x,y;
    std::cin>>x>>y;
    auto fun2=[x](const int y){return x+y;};
    std::cout<<fun2(y)<<std::endl;

    //10.16
    std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};
    elimDups(vec);
    std::stable_sort(vec.begin(),vec.end(),[](const std::string &a,const std::string &b){return a.size()<b.size();});
    std::cout<<"after stable_sort:"<<std::endl;
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;
    int n;
    std::cin>>n;
    auto iter=find_if(vec.begin(),vec.end(),
                      [n](const std::string &s){
                            return s.size()>=n;
                        });
    auto count=vec.end()-iter;
    for_each(iter,vec.end(),[](const std::string &s){std::cout<<s<<" ";});
    std::cout<<std::endl;
    return 0;
}
练习10.18:
#include <iostream>
#include <vector>
#include <algorithm>


void elimDups(std::vector<std::string > &vec){
    std::sort(vec.begin(),vec.end());
    auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器
    vec.erase(uni,vec.end());
    std::cout<<"after unique_sort and erase :"<<std::endl;
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;
}

int main()
{
    std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};
    elimDups(vec);
    stable_sort(vec.begin(),vec.end(),[](const std::string &a,const std::string &b){return a.size()<b.size();});
    std::cout<<"after stable_sort:"<<std::endl;
    for(auto x:vec) std::cout<<x<<" ";
    std::cout<<std::endl;
    int n;
    std::cin>>n;
    auto iter=partition(vec.begin(),vec.end(),
                      [n](const std::string &s){
                            return s.size()<n;
                        });
    auto count=vec.end()-iter;
    for_each(iter,vec.end(),[](const std::string &s){std::cout<<s<<" ";});
    std::cout<<std::endl;
    return 0;
}
10.3.3节练习:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};
    auto x=count_if(vec.begin(),vec.end(),[](const std::string &s){
                    return s.size()>=6;});
    std::cout<<x<<std::endl;

    int y=0;
    auto def=[=]()mutable{
        if(y==0) return true;
        else{
            --y;
            return false;}
        };

    return 0;
}

10.3.4节练习:

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std::placeholders; // bind_n操作

bool check_size(const int &x,std::string::size_type sz){return x>=sz;}

int main()
{
    std::vector<int > vec={1,3,6,8,0,3,5,12,4,2};
    std::string s="woqu";
    auto f=bind(check_size,_1,s.size());
    for(auto x:vec)
        if(f(x)){
            std::cout<<x<<std::endl;
            break;
        }
    return 0;
}
10.4.1节练习:

#include <iostream>
#include <list>
#include <vector>
#include <functional>
#include <algorithm>

int main()
{
//10.27
    std::list<int > lst={1,2,2,2,2,2,2,2,6,8};
    std::list<int > lst1;
    unique_copy(lst.begin(),lst.end(),back_inserter(lst1));
    std::cout<<"old array:";
    for_each(lst.begin(),lst.end(),[](const int &x){std::cout<<x<<" ";});
    std::cout<<std::endl;
    std::cout<<"new array:";
    for_each(lst1.begin(),lst1.end(),[](const int &x){std::cout<<x<<" ";});
    std::cout<<std::endl;

//10.28
//其中front_inserter报错   ?inserter 复制失败
    std::vector <int > vec={1,2,3,4,5,6,7,8,9};
    std::vector <int > front_vec,back_vec,rand_vec;
    auto iter=vec.begin();
    //copy(vec.begin(),vec.end(),front_inserter(front_vec));
    copy(vec.begin(),vec.end(),back_inserter(back_vec));
    copy(vec.begin(),vec.end(),inserter(vec,iter));
   // std::cout<<"front:";
    //for_each(front_vec.begin(),front_vec.end(),[](const int &x){std::cout<<x<<" ";});
    std::cout<<std::endl;
    std::cout<<"back:";
    for_each(back_vec.begin(),back_vec.end(),[](const int &x){std::cout<<x<<" ";});
    std::cout<<std::endl;
    std::cout<<"rand:";
    for_each(rand_vec.begin(),rand_vec.end(),[](const int &x){std::cout<<x<<" ";});
    std::cout<<std::endl;
    return 0;
}
10.4.2节练习:

#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include <algorithm>

//10.33
void fun(const std::string &inf_file,const std::string &outf1_file,const std::string &outf2_file){
    std::ifstream inf;
    inf.open(inf_file);
    std::istream_iterator<int > inf_iter(inf),eof;

    std::ofstream outf1;
    outf1.open(outf1_file);
    std::ofstream outf2;
    outf2.open(outf2_file);

    std::ostream_iterator<int > outf1_iter(outf1),outf2_iter(outf2);
    while(inf_iter!=eof){
        if((*inf_iter)%2) outf1<<*inf_iter;
        else outf2<<*inf_iter;
        inf_iter++;
    }
    std::cout<<"从文件\""<<inf_file<<"\"中读取数字,奇数已存入\""<<outf1_file<<"\"中,偶数已存入\""<<outf2_file<<"\"中"<<std::endl;
    inf.close();
    outf1.close();
    outf2.close();
}

int main()
{
    //10.29
    std::ifstream inf;
    inf.open("test.txt");
    std::istream_iterator<std::string > in_iter(inf); //in_ter 从文件流inf中读取类型为std::string的值
    std::istream_iterator<std::string > eof;  //文件结束位置
    std::vector<std::string> vec(in_iter,eof); //把文件的字符串读入vec中
    auto iter=vec.begin();
    while(iter!=vec.end()) std::cout<<*iter++<<" ";
    std::cout<<std::endl;
    inf.close();


    //10.30
    std::istream_iterator<int > in(std::cin); //in从输入流cin中读取类型为int的值
    std::istream_iterator<int > eof2;  //输入流结束位置
    std::vector<int > vec2(in,eof2);   //输入的数据读入vec2
    sort(vec2.begin(),vec2.end()); //排序
    std::ostream_iterator<int > out(std::cout," ");  //把类型为int的值写到输出流out中,每个值后加空格
    copy(vec2.begin(),vec2.end(),out);//vec2的值读出到out中
    std::cout<<std::endl;
    std::ostream_iterator<int > out2(std::cout," ");
    unique_copy(vec2.begin(),vec2.end(),out2); //不重复的复制
    std::cout<<std::endl;

    //10.33
    fun("num_in.txt","num_out1.txt","num_out2.txt");
    return 0;
}
10.4.3节练习:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

int main()
{
    //10.34 10.35
    std::vector <int > vec={1,2,3,4,5,6,7,8,9};
    std::vector<int >::reverse_iterator reiter=vec.rbegin(); //反向迭代器
    while(reiter!=vec.rend()) std::cout<<*reiter++<<" ";
    std::cout<<std::endl;

    std::vector<int >::iterator iter=vec.begin();    //普通迭代器
    while(iter!=vec.end()) std::cout<<*iter++<<" ";
    std::cout<<std::endl;

//10.36
    std::list<int > lis={1,2,3,0,6,4,0,1,3,2}; //查找最后一个0,返回其迭代器
    std::list<int >::reverse_iterator lis_reiter=find(lis.rbegin(),lis.rend(),0);
    std::cout<<*lis_reiter<<std::endl;

//10.37
    std::vector <int > vec2={1,2,3,4,5,6,7,8,9,10}; // 取其中 3~7 的位置复制给std::list
    std::list <int> lis2;
    auto vec2_iter=vec2.begin();
    copy(vec2_iter+2,vec2_iter+7,back_inserter(lis2));//后插迭代器实现

    for(auto x:lis2) std::cout<<x<<" ";
    std::cout<<std::endl;
    return 0;
}
11.1.1节练习:

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

//algorithm提供的string转换字母大小写函数写法
std::string fun(std::string &s){
    transform(s.begin(),s.end(),s.begin(), ::tolower);
    std::string s2;
    for(auto x:s) if(islower(x)) s2+=x; //去标点
    return s2;
}
int main()
{
    std::map<std::string  ,size_t > m;
    std::string word;
    while(std::cin>>word && word!="end") m[fun(word)]++;

    for(const auto &x:m)
        std::cout<<x.first<<" : "<<x.second<<std::endl;

    return 0;
}

11.2.1节练习:

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>


int main()
{
    std::map<std::string ,std::vector<std::string > > name;
    std::string first_name,last_name;
    while(std::cin>>first_name>>last_name && first_name!="end")
        (name[first_name]).push_back(last_name);

    for(auto x:name){
        std::cout<<x.first<<": "<<std::endl;
        for(auto y:x.second) std::cout<<y<<" ";
        std::cout<<std::endl;
    }
    return 0;
}
/*
李 胜
李 冰冰
李 连杰
刘 韶
刘 氓
刘 星
刘 亦菲
张 三丰
张 天泽
张 晓红
end e
*/
11.2.3节练习~练习11.12、练习11.13:

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>

int main()
{
    //11.12 11.13
    std::vector <std::pair<std::string ,int> > vec1,vec2,vec3;
    std::pair<std::string ,int> pa;
    while(std::cin>>pa.first>>pa.second){
        vec1.push_back({pa.first,pa.second});
        vec2.push_back(std::pair<std::string,int>(pa.first,pa.second));
        vec3.push_back(pa);
    }
    for(auto x:vec1) std::cout<<x.first<<" "<<x.second<<std::endl;

    return 0;
}
练习11.14:

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility> //pair
#include <map>

int main()
{
    //11.14
    std::map<std::string ,std::vector<std::pair<std::string,std::string> > > name;
    std::string first_name;
    std::pair<std::string,std::string> last_name;
    while(std::cin>>first_name>>last_name.first>>last_name.second && first_name!="end")
        (name[first_name]).push_back(last_name);

    for(auto x:name){
        std::cout<<x.first<<": "<<std::endl;
        for(auto y:x.second) std::cout<<y.first<<" "<<y.second<<" ";
        std::cout<<std::endl;
    }
    return 0;
}
11.3.2节练习:

#include <iostream>
#include <algorithm>
#include <map>

int main()
{
    //11.20
    std::map<std::string ,size_t > word_count;
    std::string word;
    while(std::cin>>word && word!="end"){
        std::pair< std::map<std::string ,size_t>::iterator,bool> ite=word_count.insert({word,1});
        if(!ite.second) ite.first->second++;
    }
    for(auto x:word_count)
         std::cout<<x.first<<" : "<<x.second<<std::endl;

    //11.23
    std::multimap<std::string ,std::string> name;
    std::string first_name,last_name;
    while(std::cin>>first_name>>last_name && first_name!="end")
        name.insert({first_name,last_name});

    for(auto x:name)
        std::cout<<x.first<<": "<<x.second<<std::endl;

    return 0;
}
11.3.5节练习:

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <utility>

int main()
{
    //11.31
    std::multimap<std::string ,std::string > book={{"oyy","c++ prime"},
                                    {"oyy","java plus"},
                                    {"oyy","english"},
                                    {"awei","math"},
                                    {"awei","computer"},
                                    {"baobao","taijiong"},
                                    {"baobao","gangjiong"},
                                    };
    std::string find_name="baoba";
    auto ite=book.find(find_name);
    while(ite!=book.end() && ite->first==find_name){
        ite=book.erase(ite);
    }
    for(auto x:book) std::cout<<x.first<<" "<<x.second<<std::endl;
    return 0;
}
11.3.6节练习:

#include <iostream>
#include <map>
#include <fstream>
#include <sstream>

int main()
{
//11.33
    //读取转换规则
    std::ifstream readfile("test1.txt");
    std::map<std::string ,std::string> tran;
    std::string word_first,word_second,temp;
    while(readfile>>word_first && getline(readfile,word_second))
        tran[word_first]=word_second.length()==0?word_first:word_second.substr(1);

    //读取要转的内容
    std::ifstream readfile2("test2.txt");
    std::string sentc,word;
    while(getline(readfile2,sentc)){
        std::istringstream in(sentc);
        while(in>>word){
            if(tran.find(word)!=tran.end()) std::cout<<tran[word]<<" ";
            else std::cout<<word<<" ";
        }
        std::cout<<std::endl;
    }
    return 0;
}

/*
test1.txt
brb be right back
k okay?
justkey
y why
r are
u you
pic picture
thk thanks!
l8r later

test2.txt
where r u
y dont u send me a pic
k thk l8r


*/

12.1.1节练习:

#include <iostream>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>

//12.2
class StrBlob{

typedef std::vector<std::string>  vstring;

public:
    StrBlob():data(std::make_shared<vstring>()){}
    StrBlob(std::initializer_list<std::string > lis):data(std::make_shared<vstring>(lis)){}
    vstring::size_type size()const {return data->size();}
    void push_back(const std::string &s){data->push_back(s);}
    void pop_back(){
        check(0,"pop on empty StrBlob");
        data->pop_back();
    }
    std::string &front(){
        check(0,"front on empty StrBlob");
        return data->front();
    }
    std::string &back(){
        check(0,"back on empty StrBlob");
        return data->back();
    }

private:
    std::shared_ptr<vstring> data; // emory
    void check(vstring::size_type i,const std::string &s)const {
        if(data->size()<=i) throw std::out_of_range(s); // stdexcept
    }
};
int main()
{
    //12.1
    StrBlob b1{};
    {
        StrBlob b2={"a","an","the"};
        b1=b2;
        b2.push_back("about");
    }
    std::cout<<b1.back()<<std::endl;

    StrBlob b3{"wo","qu"};
    std::cout<<b3.back()<<std::endl;
    return 0;
}
12.1.2节练习:

#include <iostream>
#include <vector>
#include <memory>

//12.6
std::vector<int > *new_vecint(){
    return new std::vector<int>;
}
void read_data(std::istream &in,std::vector<int> *&pv){ //普通指针 引用指针
    int x;
    in>>x;
    pv->push_back(x);
}

void print(std::vector<int> *&pv){
    for(auto x:*pv) std::cout<<x<<" ";
    std::cout<<std::endl;
    delete(pv);
    pv=nullptr;
}

//12.7
std::shared_ptr <std::vector<int > > ptr_vecint(){ //智能指针
    return std::make_shared<std::vector<int > > ();
    //return  shared_ptr<vector<int >> (new vector<int>(p));
}

void ptr_read_data(std::istream &in,std::shared_ptr<std::vector<int > > &spv){
    int x;
    in>>x;
    spv->push_back(x);
}
void ptr_print(std::shared_ptr<std::vector<int > > spv){
    for(auto x:*spv) std::cout<<x<<" ";
    std::cout<<std::endl;
}

int main()
{
    //12.6
    auto pv=new_vecint();
    for(int i=1;i<=3;++i) read_data(std::cin,pv);
    print(pv);

    //12.7
    auto spv=ptr_vecint();
    for(int i=1;i<=3;++i) ptr_read_data(std::cin,spv);
    ptr_print(spv);
    return 0;
}
12.1.6节练习:

#include <iostream>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <fstream>
#include <sstream>

class StrBlob{
typedef std::vector<std::string>  vstring;
public:
    friend class StrBlobPtr;
    StrBlob():data(std::make_shared<vstring>()){}
    StrBlob(std::initializer_list<std::string > lis):data(std::make_shared<vstring>(lis)){}
    vstring::size_type size()const {return data->size();}
    void push_back(const std::string &s){data->push_back(s);}
    void pop_back(){
        check(0,"pop on empty StrBlob");
        data->pop_back();
    }
    std::string &front(){
        check(0,"front on empty StrBlob");
        return data->front();
    }
    std::string &back(){
        check(0,"back on empty StrBlob");
        return data->back();
    }
private:
    std::shared_ptr<vstring> data; // memory
    void check(vstring::size_type i,const std::string &s)const {
        if(data->size()<=i) throw std::out_of_range(s); //stdexcept
    }
};
//12.19 12.20
class StrBlobPtr{
typedef std::vector<std::string>  vstring;
public :
    StrBlobPtr():curr(0){}
    StrBlobPtr(StrBlob &a,size_t sz=0):wptr(a.data),curr(sz){}
    std::string &deref() const {
        auto p=check(curr,"dereference past end");
        return (*p)[curr];
    }
    StrBlobPtr& incur(){
        check(curr,"increment past end of StrBlobPtr");
        ++curr;
        return *this;
    }
    bool empty(){
        if(curr < wptr.lock()->size()) return false;
        return true;
    }
private:
    std::shared_ptr<vstring> check(size_t i,const std::string &msg)const {
        auto ret=wptr.lock();
        if(!ret) throw std::runtime_error("unbound StrBlobPtr");
        if(ret->size() <= i)
            throw std::out_of_range(msg);
        return ret;
    }
    std::weak_ptr<vstring> wptr;
    size_t curr;
};

int main()
{
    //12.20
    std::ifstream in("in.txt");
    std::string word_s;
    StrBlob sb;
    while(getline(in,word_s)){   //从文件读入数据
        std::stringstream sin(word_s);
        std::string word;
        while(sin>>word) sb.push_back(word);
        sb.push_back("\n");
    }

    StrBlobPtr sbp(sb);  //使用StrBlob 指针类型输出StrBlob
    while(!sbp.empty()){
        std::cout<<sbp.deref()<<" ";
        sbp.incur();
    }
    return 0;
}
/*
in.txt
i think we should do it if you don't mind.
so what do you want to do?
*/
12.2.1节练习:

#include <iostream>
#include <memory>
#include <algorithm>
#include <cstring>
#include <iterator>

int main()
{
    //12.23
    char sc1[]="woqu",sc2[]=" nimeide";
    char *q=new char[strlen(sc1)+strlen(sc2)+1];
    strcpy(q,sc1);
    strcat(q,sc2);
    std::cout<<q<<std::endl;

    std::string s1="woqu",s2=" nimeide";
    std::cout<<s1+s2<<std::endl;
    delete [] q;

    // need to tell the size. 12.24
    std::cout << "How long do you want the string? ";
    int size(0);
    std::cin >> size;
    char* input = new char[size + 1]();
    std::cin.ignore(); //读取多余回车
    std::cout << "input the string: ";
    std::cin.get(input, size + 1);
    std::cout << input;
    delete[] input;

    return 0;
}

12.2.2节练习:


#include <iostream>
#include <memory>

//12.26
int main()
{
    int n;
    std::cout<<"please input size:";
    std::cin>>n;
    std::cin.ignore();
    std::allocator<std::string > t;  //定义类型对象
    auto const p = t.allocate(n); //申请内存
    auto q=p;
    std::string word;
    while(q!=p+n && std::cin>>word) t.construct(q++,word); //调用构造函数
    while(q!=p){
        std::cout<<*--q<<std::endl;
        t.destroy(q);  //调用析构函数,释放对象
    }
    t.deallocate(p,n); //释放内存
    return 0;
}
12.3.1节练习:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>

//12.28
typedef std::vector<std::string >::size_type line;

int main()
{
    std::vector<std::string > text;
    std::map<std::string ,std::set<line> > sign;
    std::string file_name;
    std::cout<<"enter file name : "<<std::endl;
    std::cin>>file_name;
    std::cin.ignore();
    std::ifstream file_input(file_name);
    std::string senten,word;

    while(getline(file_input,senten)){ //读入文件内容
        text.push_back(senten);
        std::stringstream word_in(senten);
        line len=text.size();
        while(word_in>>word) sign[word].insert(len);
    }

    while(true){  //查询
        std::cout<<"enter the query word and enter q to quit : ";
        std::cin>>word;
        std::cin.ignore();
        if(word=="q") break;
        auto loc=sign.find(word);
        if(loc==sign.cend()) std::cout<<"not find "<<word<<std::endl;
        else {
            std::cout<<word<<" : "<<std::endl;
            for(auto x:loc->second)
                std::cout<<"(line "<<x<<") : "<<text[x-1]<<std::endl;
        }
    }
    return 0;
}
12.3.2节练习:

练习12.30:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>
//12.30 同12.27
class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public :
    //构造函数 获取一个文件输入对象 构造 sign p_text
    TextQuery(std::ifstream& in):p_text(new std::vector<std::string >){
        std::string senten;  //读取每行的句子
        while(getline(in,senten)){
            p_text->push_back(senten);
            auto len=p_text->size();
            std::stringstream word_in(senten);
            std::string word;
            while(word_in>>word){
                auto isok=sign.find(word);
                 //若该单词还为出现过,申请新的空间
                if(isok==sign.cend()) sign[word].reset(new std::set<line>);
                sign[word]->insert(len);
            }
        }
    }
     //该函数的定义必须在QueryResult 完整定义后定义,这里只做声明
    QueryResult query(const std::string &s)const ;
private :
    std::shared_ptr<std::vector<std::string > > p_text;  //存内容
    std::map<std::string,std::shared_ptr<std::set<line> > > sign; //存每个单词所在行位置数
};

//查询结果类 包括查询的单词 以及该单词所在的所有行数 单词所在行的句子(即必须获取所有内容)
class QueryResult{
private:
    std::string word;   //查询的单词
    std::shared_ptr<std::set<line> > p_line; //该单词的行号
    std::shared_ptr<std::vector<std::string> >p_text; //存句子
public :
    //print要使用里面的成员
    friend std::ostream& print(std::ostream& out,const QueryResult& qr);
    QueryResult(std::string s,
                std::shared_ptr<std::set<line> > pl,
                std::shared_ptr<std::vector<std::string> > pv):
                word(s),p_line(pl),p_text(pv){}
};
QueryResult TextQuery::query(const std::string &s)const{
    std::shared_ptr<std::set<line> > null_ptr(new std::set<line> );
    auto isok=sign.find(s);
    //若未找到,返回第二个参数为新申请的初始化的空间
    if(isok==sign.cend()) return QueryResult(s,null_ptr,p_text);
    else return QueryResult(s,isok->second,p_text);
}
std::ostream& print(std::ostream& out,const QueryResult &qr){
    out<<qr.word<<" : "<<std::endl;
    for(auto x:*qr.p_line) out<<"(line "<<x<<" ): "<<qr.p_text->at(x-1)<<std::endl;
    return out;
}
void runQueries(std::ifstream &infile){
    TextQuery tq(infile);
    while(true){
        std::cout<<"enter word to look for, or q to quit: ";
        std::string s;
        if(!(std::cin>>s) || s=="q") break;
        print(std::cout,tq.query(s))<<std::endl;
    }
}
int main()
{
    std::ifstream in("in.txt");
    runQueries(in);
    return 0;
}
练习12.32:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>
#include <stdexcept>
//12.32
class StrBlob{

typedef std::vector<std::string>  vstring;

public:
    StrBlob():data(std::make_shared<vstring>()){}
    StrBlob(std::initializer_list<std::string > lis):data(std::make_shared<vstring>(lis)){}
    vstring::size_type size()const {return data->size();}
    void push_back(const std::string &s){data->push_back(s);}
    void pop_back(){
        check(0,"pop on empty StrBlob");
        data->pop_back();
    }
    std::string &front(){
        check(0,"front on empty StrBlob");
        return data->front();
    }
    std::string &back(){
        check(0,"back on empty StrBlob");
        return data->back();
    }
    std::string at(int x){
        return data->at(x);
    }
private:
    std::shared_ptr<vstring> data; // emory
    void check(vstring::size_type i,const std::string &s)const {
        if(data->size()<=i) throw std::out_of_range(s); // stdexcept
    }
};

class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public :
    //构造函数 获取一个文件输入对象 构造 sign p_text
    TextQuery(std::ifstream& in):p_text(new StrBlob){
        std::string senten;  //读取每行的句子
        while(getline(in,senten)){
            p_text->push_back(senten);
            auto len=p_text->size();
            std::stringstream word_in(senten);
            std::string word;
            while(word_in>>word){
                auto isok=sign.find(word);
                 //若该单词还为出现过,申请新的空间
                if(isok==sign.cend()) sign[word].reset(new std::set<line>);
                sign[word]->insert(len);
            }
        }
    }
     //该函数的定义必须在QueryResult 完整定义后定义,这里只做声明
    QueryResult query(const std::string &s)const ;
private :
    std::shared_ptr<StrBlob > p_text;  //存内容
    std::map<std::string,std::shared_ptr<std::set<line> > > sign; //存每个单词所在行位置数
};

//查询结果类 包括查询的单词 以及该单词所在的所有行数 单词所在行的句子(即必须获取所有内容)
class QueryResult{
private:
    std::string word;   //查询的单词
    std::shared_ptr<std::set<line> > p_line; //该单词的行号
    std::shared_ptr<StrBlob >p_text; //存句子
public :
    //print要使用里面的成员
    friend std::ostream& print(std::ostream& out,const QueryResult& qr);
    QueryResult(std::string s,
                std::shared_ptr<std::set<line> > pl,
                std::shared_ptr<StrBlob > pv):
                word(s),p_line(pl),p_text(pv){}
};
QueryResult TextQuery::query(const std::string &s)const{
    std::shared_ptr<std::set<line> > null_ptr(new std::set<line> );
    auto isok=sign.find(s);
    //若未找到,返回第二个参数为新申请的初始化的空间
    if(isok==sign.cend()) return QueryResult(s,null_ptr,p_text);
    else return QueryResult(s,isok->second,p_text);
}
std::ostream& print(std::ostream& out,const QueryResult &qr){
    out<<qr.word<<" : "<<std::endl;
    for(auto x:*qr.p_line)
        out<<"(line "<<x<<" ): "<<qr.p_text->at(x-1)<<std::endl;
    return out;
}
void runQueries(std::ifstream &infile){
    TextQuery tq(infile);
    while(true){
        std::cout<<"enter word to look for, or q to quit: ";
        std::string s;
        if(!(std::cin>>s) || s=="q") break;
        print(std::cout,tq.query(s))<<std::endl;
    }
}

int main()
{
    std::ifstream in("in.txt");
    runQueries(in);
    return 0;
}
练习12.33:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>
//12.30 同12.27

class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public :
    //构造函数 获取一个文件输入对象 构造 sign p_text
    TextQuery(std::ifstream& in):p_text(new std::vector<std::string >){
        std::string senten;  //读取每行的句子
        while(getline(in,senten)){
            p_text->push_back(senten);
            auto len=p_text->size();
            std::stringstream word_in(senten);
            std::string word;
            while(word_in>>word){
                auto isok=sign.find(word);
                 //若该单词还为出现过,申请新的空间
                if(isok==sign.cend()) sign[word].reset(new std::set<line>);
                sign[word]->insert(len);
            }
        }
    }
     //该函数的定义必须在QueryResult 完整定义后定义,这里只做声明
    QueryResult query(const std::string &s)const ;
private :
    std::shared_ptr<std::vector<std::string > > p_text;  //存内容
    std::map<std::string,std::shared_ptr<std::set<line> > > sign; //存每个单词所在行位置数
};

//查询结果类 包括查询的单词 以及该单词所在的所有行数 单词所在行的句子(即必须获取所有内容)
class QueryResult{
private:
    std::string word;   //查询的单词
    std::shared_ptr<std::set<line> > p_line; //该单词的行号
    std::shared_ptr<std::vector<std::string> >p_text; //存句子
public :
    //print要使用里面的成员
    friend std::ostream& print(std::ostream& out,const QueryResult& qr);
    QueryResult(std::string s,
                std::shared_ptr<std::set<line> > pl,
                std::shared_ptr<std::vector<std::string> > pv):
                word(s),p_line(pl),p_text(pv){}
    std::set<line >::iterator begin(){   //begin
        return p_line->begin();
    }
    std::set<line >::iterator end(){   //end
        return p_line->end();
    }
    std::shared_ptr<std::vector<std::string> > get_file(){ //get_file
        return p_text;
    }
};
QueryResult TextQuery::query(const std::string &s)const{
    std::shared_ptr<std::set<line> > null_ptr(new std::set<line> );
    auto isok=sign.find(s);
    //若未找到,返回第二个参数为新申请的初始化的空间
    if(isok==sign.cend()) return QueryResult(s,null_ptr,p_text);
    else return QueryResult(s,isok->second,p_text);
}
std::ostream& print(std::ostream& out,const QueryResult &qr){
    out<<qr.word<<" : "<<std::endl;
    for(auto x:*qr.p_line) out<<"(line "<<x<<" ): "<<qr.p_text->at(x-1)<<std::endl;
    return out;
}
void runQueries(std::ifstream &infile){
    TextQuery tq(infile);
    while(true){
        std::cout<<"enter word to look for, or q to quit: ";
        std::string s;
        if(!(std::cin>>s) || s=="q") break;
        print(std::cout,tq.query(s))<<std::endl;
    }
}

int main()
{
    return 0;
}
15.2.1节练习:

#include <iostream>

//15.3
class Quote{
public :
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}
    std::string isbn()const {return bookNo;}
    virtual double net_price(std::size_t n) const {return n*price;}
    friend double print_total(std::ostream&,const Quote&,size_t );
private:
    std::string bookNo;
protected:
    double price=0.0;
};

double print_total(std::ostream &os,const Quote &item,size_t n){
    double ret=item.net_price(n);
    os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;
    return ret;
}
int main()
{
    Quote q("c++ prime",150);
    print_total(std::cout,q,3);
    return 0;
}
15.2.2节练习:

#include <iostream>
#include <cstdio>

//15.5 15.6 15.7
class Quote{
public :
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}
    std::string isbn()const {return bookNo;}
    virtual double net_price(std::size_t n) const {return n*price;}
    friend double print_total(std::ostream&,const Quote&,size_t );
private:
    std::string bookNo;
protected:
    double price=0.0;
};

class Bulk_quote:public Quote{
public :
    Bulk_quote()=default;
    Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):
        Quote(book,sales_price),min_num(num),discount(disc){};
    double net_price(std::size_t n) const{
        if(n>=min_num) return n*price*discount;
        else return n*price;
    }
private:
    std::size_t min_num;
    double discount;
};

class huodong_quote:public Quote{
public :
    huodong_quote()=default;
    huodong_quote(const std::string book,double sales_price,std::size_t num,double disc):
        Quote(book,sales_price),max_num(num),discount(disc){}
    double net_price(std::size_t n)const {
        if(n<=max_num) return n*price*discount;
        else return net_price(max_num)+(n-max_num)*price;
    }
private:
    double discount;
    size_t max_num;
};
double print_total(std::ostream &os,const Quote &item,size_t n){
    double ret=item.net_price(n);
    os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;
    return ret;
}

int main()
{

    Bulk_quote b("math",20,5,0.5);
    print_total(std::cout,b,4);
    print_total(std::cout,b,5);

    huodong_quote h("高数",20,5,0.5);
    print_total(std::cout,h,5);
    print_total(std::cout,h,6);
    return 0;
}
15.3节练习:

#include <iostream>
#include <cstdio>


//15.11  debug()
class Quote{
public :
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}
    std::string isbn()const {return bookNo;}
    virtual double net_price(std::size_t n) const {return n*price;}
    friend double print_total(std::ostream&,const Quote&,size_t );
    virtual void debug(){
        std::cout<<"类成员及类型如下所示:"<<std::endl;
        std::cout<<"string : bookNo"<<std::endl;
        std::cout<<"double : price"<<std::endl;
    }
private:
    std::string bookNo;
protected:
    double price=0.0;
};

class Bulk_quote:public Quote{
public :
    Bulk_quote()=default;
    Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):
        Quote(book,sales_price),min_num(num),discount(disc){};
    double net_price(std::size_t n) const{
        if(n>=min_num) return n*price*discount;
        else return n*price;
    }
    void debug()override{
        Quote::debug();
        std::cout<<"size_t : min_num"<<std::endl;
        std::cout<<"double : discount"<<std::endl;
    }
private:
    std::size_t min_num;
    double discount;
};

class huodong_quote:public Quote{
public :
    huodong_quote()=default;
    huodong_quote(const std::string book,double sales_price,std::size_t num,double disc):
        Quote(book,sales_price),max_num(num),discount(disc){}
    double net_price(std::size_t n)const {
        if(n<=max_num) return n*price*discount;
        else return net_price(max_num)+(n-max_num)*price;
    }
    void debug()override{
        Quote::debug();
        std::cout<<"size_t : max_num"<<std::endl;
        std::cout<<"double : discount"<<std::endl;
    }
private:
    double discount;
    size_t max_num;
};
double print_total(std::ostream &os,const Quote &item,size_t n){
    double ret=item.net_price(n);
    os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;
    return ret;
}

int main()
{
    Bulk_quote b("math",20,5,0.5);
    huodong_quote h("数学",20,5,0.5);
    b.debug();
    std::cout<<std::endl;
    h.debug();
    return 0;
}
15.4节练习:

#include <iostream>
#include <cstdio>


//15.15 15.16
class Quote{
public :
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}
    std::string isbn()const {return bookNo;}
    virtual double net_price(std::size_t n) const {return n*price;}
    friend double print_total(std::ostream&,const Quote&,size_t );
private:
    std::string bookNo;
protected:
    double price=0.0;
};
double print_total(std::ostream &os,const Quote &item,size_t n){
    double ret=item.net_price(n);
    os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;
    return ret;
}
class Disc_quote:public Quote{
public :
    Disc_quote()=default;
    Disc_quote(const std::string &book,double sales_price,std::size_t n,double disc):
        Quote(book,sales_price),off_num(n),discount(disc){}
    double net_price(size_t)const =0;  //´¿Ð麯Êý
protected:
    size_t off_num;
    double discount;
};
class Bulk_quote:public Disc_quote{
public :
    Bulk_quote()=default;
    Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):
        Disc_quote(book,sales_price,num,disc){};
    double net_price(std::size_t n) const override{
        if(n>=off_num) return n*price*discount;
        else return n*price;
    }
};

class huodong_quote:public Disc_quote{
public :
    huodong_quote()=default;
    huodong_quote(const std::string book,double sales_price,std::size_t num,double disc):
        Disc_quote(book,sales_price,num,disc){}
    double net_price(std::size_t n)const override{
        if(n<=off_num) return n*price*discount;
        else return net_price(off_num)+(n-off_num)*price;
    }
};
int main()
{
    Bulk_quote b("高数",20,5,0.5);
    huodong_quote h("线代",20,5,0.5);
    print_total(std::cout,b,6);
    print_total(std::cout,h,6);
    return 0;
}
15.5节练习:

#include <iostream>
#include <cmath>

//15.21 15.22
class Graph{
public :
    Graph()=default;
    Graph(double x):r(x){}
    virtual double get_area()=0;
    virtual double get_value()=0;
protected:
    double r;
    const double Pi=3.1415926;
};

class Grid:public Graph{
public :
    Grid()=default;
    Grid(double x):Graph(x){}
    double get_area(){return r*r;}
    double get_value(){return 0.0;}
};
class Circle:public Graph{
public :
    Circle()=default;
    Circle(double x):Graph(x){}
    double get_area(){return Pi*r*r;}
    double get_value(){return 0.0;}
};

class Ball:public Graph{
public :
    Ball()=default;
    Ball(double x):Graph(x){}
    double get_area(){return 4.0*Pi*r*r;}
    double get_value(){return 4.0*Pi*r*r*r/3.0;}
};

class Cone:public Graph{
public :
    Cone()=default;
    Cone(double x,double y):Graph(x),height(y){}
    double get_area(){return Pi*r*r+Pi*r*sqrt(height*height+r*r);}
    double get_value(){return Pi*height*r*r/3.0;}
protected:
    double height;
};
int main()
{
    Grid g(2.0);
    Circle ci(2.0);
    Ball b(2.0);
    Cone co(2.0,3.0);
    std::cout<<"Grid : "<<g.get_area()<<" m^2 "<<g.get_value()<<" m^3 "<<std::endl;
    std::cout<<"Cirle : "<<ci.get_area()<<" m^2 "<<ci.get_value()<<" m^3 "<<std::endl;
    std::cout<<"Ball : "<<b.get_area()<<" m^2 "<<b.get_value()<<" m^3 "<<std::endl;
    std::cout<<"Cone : "<<co.get_area()<<" m^2 "<<co.get_value()<<" m^3 "<<std::endl;
    return 0;
}
15.7.3节练习:

#include <iostream>

//15.26
class Quote{
public :
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){
        std::cout<<"Quote construct "<<std::endl;
    }
    Quote(const Quote &qu){
        this->bookNo=qu.bookNo;
        this->price=qu.price;
        std::cout<<"Quote copy "<<std::endl;
    }
    std::string isbn()const {return bookNo;}
    virtual ~Quote(){
        std::cout<<"Quote delete"<<std::endl;
    }
private:
    std::string bookNo;
protected:
    double price=0.0;
};

class Bulk_quote:public Quote{
public :
    Bulk_quote()=default;
    Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):
        Quote(book,sales_price),min_num(num),discount(disc){
            std::cout<<"Bulk_quote construct "<<std::endl;
        };
    Bulk_quote(const Bulk_quote &bkq):Quote(bkq){
        this->min_num=bkq.min_num;
        this->discount=bkq.discount;
        std::cout<<"Bulk_quote copy "<<std::endl;
    }
    virtual ~Bulk_quote(){
        std::cout<<"Bulk_quote delete "<<std::endl;
    }
private:
    std::size_t min_num;
    double discount;
};

int main()
{
    Bulk_quote b("math",20,5,0.5);
    Bulk_quote bb(b);
    return 0;
}

/* 首位两行为b调用构造函数及析构函数, 中间四行为bb调用拷贝函数及析构函数
Quote construct
Bulk_quote construct

Quote copy
Bulk_quote copy
Bulk_quote delete
Quote delete

Bulk_quote delete
Quote delete
*/
15.8节练习:

#include <iostream>
#include <cstdio>
#include <vector>
#include <memory>

//15.28 15.29
class Quote{
public :
    Quote()=default;
    Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}
    std::string isbn()const {return bookNo;}
    virtual double net_price(std::size_t n) const {return n*price;}
    friend double print_total(std::ostream&,const Quote&,size_t );
private:
    std::string bookNo;
protected:
    double price=0.0;
};

class Bulk_quote:public Quote{
public :
    Bulk_quote()=default;
    Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):
        Quote(book,sales_price),min_num(num),discount(disc){};
    double net_price(std::size_t n) const{
        if(n>=min_num) return n*price*discount;
        else return n*price;
    }
private:
    std::size_t min_num;
    double discount;
};
double print_total(std::ostream &os,const Quote &item,size_t n){
    double ret=item.net_price(n);
    os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;
    return ret;
}

int main()
{
    std::vector<Quote > vec1;
    vec1.push_back(Bulk_quote("高数",20,8,0.5));//只是把其中Quote的部分拷贝给vec1了
    vec1.push_back(Bulk_quote("高数",20,5,0.5));
    double sum1=0.0;
    for(auto x:vec1){
        sum1+=print_total(std::cout,x,7);
    }
    std::cout<<"total_price:"<<sum1<<std::endl;

    std::vector<std::shared_ptr<Quote> > vec2;
    vec2.push_back(std::make_shared<Bulk_quote>("高数",20,8,0.5)); //指针动态绑定
    vec2.push_back(std::make_shared<Bulk_quote>("高数",20,5,0.5));
    double sum2=0.0;
    for(auto x:vec2){
        sum2+=print_total(std::cout,*x,7);
    }
    std::cout<<"total_price:"<<sum2<<std::endl;
    return 0;
}
15.8.1节练习:

#incl

以上是关于C++ Primer 第五版 部分课后题答案的主要内容,如果未能解决你的问题,请参考以下文章

C++ Primer(第五版) 整理和总结

C++PRIMER第五版练习题答案第一章

C语言程序设计第五版 谭浩强 第五版课后答案

C程序设计(谭浩强)第五版课后题答案 第六章

电子技术基础数字部分 第五版 第六版 课后习题答案

电子技术基础模拟部分 第五版 第六版 课后习题答案