C++ Primer 答案 第十二章

12.1
都是4个,但是b2已经没了,如果接着使用b2会出错
b1 = b2;
b2.push_back("about");
它们共用了内存,所以对b2操作,b1的size也变了

12.2
我把头文件和实现写在一起了
解释下为啥要重构front和back:
如果我们定义的是const的StrBlob,调用front(),它的返回值是string&,
return data->front; 这里的data->front是const类型的,不能用普通引用类型接受const类型
StrBlob.h

#ifndef PRO1_STRBLOB_H
#define PRO1_STRBLOB_H

#include <vector>
#include <string>
using namespace std;

class StrBlob {
public:
    typedef vector<string>::size_type size_type;
    StrBlob():data(make_shared<vector<string>>()) { }
    StrBlob(initializer_list<string> il): data(make_shared<vector<string>>(il)) {}
    size_type size() const { return data->size();}
    bool empty() const { return data->empty();}
    void push_back(const string &t) {data->push_back(t);}
    void pop_back()
    {
        check(0, "pop_back om empty StrBlob");
        data->pop_back();
    }
    string& front()
    {
        check(0, "front on empty StrBlob");
        return data->front();
    }
    string& back()
    {
        check(0, "back on empty StrBlob");
        return data->back();
    }
    //重构front和back
    const string& front() const 
    {
        check(0, "front on empty StrBlob");
        return data->front();
    }
    const string& back() const
    {
        check(0, "back on empty StrBlob");
        return data->back();
    }
private:
    shared_ptr<vector<string>> data;
    void check(size_type i, const string &msg) const
    {
        if(i >= data->size())
            throw out_of_range(msg);
    }
};
#endif //PRO1_STRBLOB_H

12.3
不需要,因为它们的返回值是void

12.4
size_type 是 unsign 类型,是不小于0的

12.6

#include <iostream>
#include <string>
#include <vector>
using namespace std;

vector<int> *dver()
{
    return new vector<int>();
}
void lver(vector<int> * &pver)
{
    int i;
    while(cin >> i && i != 99)
        pver->push_back(i);
}
void printver(vector<int> * &pver)
{
    for(const auto &i : *pver)
        cout << i << " ";
    cout << endl;
}
int main(int argc, char *argv[])
{
    vector<int> *pvec = dver();
    lver(pvec);
    printver(pvec);
    delete(pvec);
    return 0;
}
/*输出:
1
2
3
4
99
1 2 3 4 
*/

12.7

#include <iostream>
#include <string>
#include <vector>
using namespace std;

shared_ptr<vector<int>> dver()
{
    return make_shared<vector<int>>();
}
void lver(shared_ptr<vector<int>> pver)
{
    int i;
    while(cin >> i && i != 99)
        pver->push_back(i);
}
void printver(shared_ptr<vector<int>> pver)
{
    for(const auto &i : *pver)
        cout << i << " ";
    cout << endl;
}
int main(int argc, char *argv[])
{
    auto pvec = dver();
    lver(pvec);
    printver(pvec);
    return 0;
}
/*输出:
1
2
3
4
99
1 2 3 4 
*/


12.8
用bool接收指针,该指针就永远无法delete了

12.9
这个例子很好的说明了智能指针的优势
前两行:
r原来申请的(int)100 无法回收了
后两行:
使用智能指针,由于r改变指向,其内置计数器减1变为0,(int)100自动回收

12.10
合法

12.11
这句话初始化了一个临时的shared_ptr,注意这不是copy,它是独立的,内存的引用次数为1,(注意它指的内存和之前的p一样)函数结束时销毁临时变量,引用次数减1,变为0,内存自动回收(p也成了空悬指针)。

12.12
(a)合法且正确,拷贝智能指针,引用次数变为2,函数结束次数变为1
(b)不合法,shared_ptr<int> ptr=new int(); 这句话不合法,不能这样初始化,
   只能直接初始化  shared_ptr<int> ptr(new int()); 
(c)不合法,和(b)一样
(d)合法,但是它让new指针变成智能指针,所指内存引用次数为1,函数结束次数变为0,内存回收

12.13
malloc: *** error for object 0x7fb34a400658: pointer being freed was not allocated
我的理解是p不是new指针,不能用delete

12.16
拷贝:
call to implicitly-deleted copy constructor of 'unique_ptr<int>'
赋值:
object of type 'std::__1::unique_ptr<int, std::__1::default_delete<int> >' cannot be assigned because its copy assignment operator is implicitly deleted

12.17
(a)不合法
(b)不合法
(c)合法,但是参照12.12(d),后续可能造成泄漏
(d)不合法
(e)合法而且正确
(f)不合法

12.23

#include <iostream>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    const char* c1 = "cat";
    const char* c2 = "bird";
    char *r1 = new char[strlen(c1) + strlen(c2)]();
    strcat(r1, c1);
    strcat(r1, c2);
    cout << r1 << endl;
    delete[] r1;
    string s1 = "cat";
    string s2 = "bird";
    char *r2 = new char[s1.size() + s2.size()]();
    strcat(r2, s1.c_str());
    strcat(r2, s2.c_str());
    cout << r2 <<endl;
    delete[] r2;
    return 0;
}

12.24

#include <iostream>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    string s;
    cin >> s;
    char *pc = new char[s.size()]();
    strcat(pc, s.c_str());
    cout << pc << endl;
    delete [] pc;
    return 0;
}
//dog
//dog

12.25
delete [] pa;

12.26

#include <iostream>
#include <string>
#include <memory>
using namespace std;

int main(int argc, char *argv[])
{
    allocator<string> alloc;
    size_t i = 5;
    auto const p = alloc.allocate(i); //分配内存
    string s;
    auto q = p;
    while(cin >> s && q != p + i)
        alloc.construct(q++, s); //构造
    while (q != p)
    {
        cout << *--q << " ";
        alloc.destroy(q); //析构
    }
    alloc.deallocate(p,i);  //释放内存
    return 0;
}
/*输出:
aa
bb
cc
dd
ee
ff
ee dd cc bb aa 
*/

12.29
我觉得差不多
do{
    
}
while(true);

12.30
TextQuery.h

#ifndef PRO1_TEXTQUERY_H
#define PRO1_TEXTQUERY_H

#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
using namespace std;

class QueryResult;
class TextQuery {
public:
    using line_no= vector<string>::size_type;
    explicit TextQuery(ifstream &);
    QueryResult query(const string &) const;

private:
    shared_ptr<vector<string>> file;
    map<string, shared_ptr<set<line_no>>> wm;
};

class QueryResult {

    friend ostream& print(ostream&, const QueryResult&);
public:
    QueryResult(const string &s, shared_ptr<set<TextQuery::line_no>> p, shared_ptr<vector<string>> f):
    sought(s), lines(p), file(f) {}

private:
    string sought;
    shared_ptr<set<size_t >> lines;
    shared_ptr<vector<string>> file;
};
ostream& print(ostream&, const QueryResult&);

#endif //PRO1_TEXTQUERY_H

TextQuery.cpp

#include "TextQuery.h"

TextQuery::TextQuery(ifstream &is) :file(new vector<string>)
{
    string text;
    while(getline(is, text))
    {
        file->push_back(text);
        size_t n = file->size() - 1; //行号
        istringstream line(text);
        string word;
        while(line >> word)
        {
            auto &lines = wm[word];
            if(!lines)
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}

QueryResult TextQuery::query(const string &sought) const
{
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    auto loc = wm.find(sought);
    if(loc == wm.end())
        return QueryResult(sought, nodata, file);
    else
        return QueryResult(sought, loc->second, file);
}

ostream& print(ostream& os, const QueryResult& qr)
{
    os << qr.sought << " occurs " <<qr.lines->size() << " times" << endl;
    for(auto num : *qr.lines)
        os << "\t(line " << num + 1 << ") "
        << *(qr.file->begin() + num ) << endl;
    return os;
}

main.cpp

#include <iostream>
#include <string>
#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 file("test.txt");
    runQueries(file);
    return 0;
}
/*输出
enter word to look for, or q to quit: love
love occurs 9 times
    (line 5) Teaching me the meaning of love 
    (line 14) I fell in love with you. 
    (line 20) That makes our love strong 
    (line 25) My love is like the grasses 
    (line 29) I love to be the one you always think of, 
    (line 31) I'll always love to be the one you love. 
    (line 66) What does it matter that my love could not keep her, 
    (line 75) I no longer love her,that's certain,but how I loved her. 
    (line 79) I no longer love her,that's certain,but maybe I love her. 

enter word to look for, or q to quit: q

Process finished with exit code 0
*/

12.31
如果同一行出现一个单词两次,vector就会重复

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值