《C++ Premier》第5版 第12章 动态内存(智能指针)读书笔记


《C++ Premier》第5版 第12章 动态内存(智能指针) 讲解了
shared_ptr
weak_ptr
unique_ptr
但是没有讲解多线程情况下(在公司中)如何安全的使用智能指针
进阶学习,参看《C++标准库 第2版》侯捷译 5.2 Smart Pointer(智能指针) P76



12.3 使用标准库:文本查询程序

这个程序特别棒,可以初窥面向对象编程思想 ,可以看到如何通过代码展现面向对象编程

querymain.cpp

#include <string>
using std::string;

#include <fstream>
using std::ifstream;

#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;

#include <cstdlib>

#include "TextQuery.h"

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;
    if (argc < 2 || !(infile.open(argv[1]), infile))
    {
        cerr << "No input file!" << endl;
        return EXIT_FAILURE;
    }
    runQueries(infile);
    return 0;
}

TextQuery.h

#ifndef TEXTQUERY_H
#define TEXTQUERY_H

#include <memory>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <fstream>
#include "QueryResult.h"

using std::ifstream;
using std::map;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;

inline string make_plural(size_t ctr,
                          const string &word,
                          const string &ending)
{
    return (ctr > 1) ? word + ending : word;
}

class QueryResult;

class TextQuery
{
public:
    typedef size_t line_no;

public:
    TextQuery(ifstream &);
    QueryResult query(const string &) const;
    void display_map(); //请勿随便调用,因为数据量大 会把终端卡崩溃

private:
    shared_ptr<vector<string>> file;
    map<string, shared_ptr<set<line_no>>> wm;
    static string cleanup_str(const string &);
};
#endif

TextQuery.cpp

#include "TextQuery.h"
#include "QueryResult.h"

#include <cstddef>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
#include <utility>

using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::getline;
using std::ifstream;
using std::ispunct;
using std::istringstream;
using std::map;
using std::ostream;
using std::pair;
using std::set;
using std::shared_ptr;
using std::size_t;
using std::string;
using std::strlen;
using std::tolower;
using std::vector;

/**
 * 构造函数
 * 读取文件内存,存入file所指向的vector<string>>
 * 针对每一行中的,每个单词,存到map中
 * 每个单词对应于map中的一项,first是单词本身,second是单词所在行的set集合
*/
TextQuery::TextQuery(ifstream &is) : file(new vector<string>)
{
    string text;
    while (getline(is, text))
    {
        file->push_back(text);
        int n = file->size() - 1; //行当前的下标(从0开始)
        istringstream line(text);
        string word;
        while (line >> word)
        {
            word = cleanup_str(word);
            shared_ptr<set<line_no>> &lines = wm[word];
            if (!lines)
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}

/**
 * 是标点符号,则去除
 * 不是标点符号,则全部转换为小写字母;这样就不对大小写敏感了
*/
string TextQuery::cleanup_str(const string &word)
{
    string ret;
    for (string::const_iterator it = word.begin(); it != word.end(); ++it)
    {
        if (!ispunct(*it))
            ret += tolower(*it);
    }
    return ret;
}

QueryResult TextQuery::query(const string &sought) const
{
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    auto loc = wm.find(cleanup_str(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() << " "
       << make_plural(qr.lines->size(), "time", "s") << endl;

    for (QueryResult::line_no num : *qr.lines)
        os << "\t(line " << num + 1 << ") "
           << *(qr.file->begin() + num) << endl;
    return os;
}
void TextQuery::display_map()
{
    map<string, shared_ptr<set<line_no>>>::iterator iter = wm.begin();
    map<string, shared_ptr<set<line_no>>>::iterator iter_end = wm.end();

    for (; iter != iter_end; ++iter)
    {
        cout << "word: " << iter->first << " {";

        shared_ptr<set<line_no>> text_locs = iter->second;
        set<line_no>::iterator loc_iter = text_locs->cbegin();
        set<line_no>::iterator loc_iter_end = text_locs->cend();

        while (loc_iter != loc_iter_end)
        {
            cout << *loc_iter;
            if (++loc_iter_end != loc_iter_end)
                cout << ", ";
        }

        cout << "}\n";
    }
    cout << endl;
}

QueryResult.h

#ifndef QUERYRESULT_H
#define QUERYRESULT_H

#include <memory>
#include <string>
#include <vector>
#include <set>
#include <iostream>
using std::map;
using std::ostream;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;

class QueryResult
{
    friend ostream &print(ostream &, const QueryResult &);

public:
    typedef size_t line_no;
    typedef set<line_no>::const_iterator line_it;

public:
    QueryResult(string s,
                shared_ptr<set<line_no>> p,
                shared_ptr<vector<string>> f)
        : sought(s),
          lines(p),
          file(f)
    {
    }
    line_no size() const { return lines->size(); }
    line_it begin() const { return lines->cbegin(); }
    line_it end() const { return lines->cend(); }
    shared_ptr<vector<string>> get_file() { return file; };

private:
    string sought;                   //查询哪个单词
    shared_ptr<set<line_no>> lines;  //单词所在的行--已经存储在set集合中了
    shared_ptr<vector<string>> file; //指向文件内容
};

ostream &print(ostream &, const QueryResult &);
#endif
### 回答1: 格外实用的c语言编程书籍——premier电子。它是由Prata编写的,是一本<classic>级别的大部头教材,对c语言的各个方面进行了细致地讲解。该书在全球范围内广受好评,被誉为c语言编程经典入门读物。相较于传统的纸质,电子更具备便携性和交互性两大特点。在电子上,你可以轻松地进行文字搜索、节跳转、笔记记录等操作,在阅读体验上更为人性化,使你更好地掌握知识。 此书内容详尽、深入浅出,对想从事c语言编程的软件工程师具有广泛的适用性,从初学者到进阶者都能够从中获益良多。全书共计1100多页,涵盖了c语言的基础知识和高级应用,包括数据类型、流控制语句、结构体、函数、指针、内存管理等等。同时,该书中还有大量的示例代码和练习题,非常适合用来辅助学习和巩固所学知识。 总之,c语言是计算机编程语言中必不可少的一门,而premier电子则是学习c语言的必备工具书。不管是从事软件开发的新手,还是追求技术深度的老手,都能够从这本书中汲取到宝贵的知识,帮助他们更好地编写优秀的程序。 ### 回答2: c premier是一种用于C语言编程的电子本集成开发环境(IDE),它可以提供一个完整的开发环境,包括编辑器、编译器和调试器。使用c premier电子可以方便地编写和管理C语言程序,加速开发流程,减少开发错误。c premier具有先进的功能,如语法突出显示、自动完成和脚本编写等,可用于各种类型的C语言程序开发包括嵌入式系统、桌面应用程序等。此外,c premier还具有强大的调试器,可以帮助开发人员查找和修复程序中的错误。c premier电子的优势之一是它可以在不同平台上运行,包括Windows、Mac和Linux系统。总之,c premier电子是一种非常实用的C语言开发环境,可以轻松编写高质量的C语言程序。 ### 回答3: Premier电子是一种数字化的电子期刊,主要用于在线发布、订阅和阅读相关的经济、商业、金融和管理等领域的文和研究。该电子的优势在于其能够提供便利快捷的服务,用户无需购买实体本,通过在线订阅即可随时随地浏览该刊物,方便用户学习和参考。此外,Premier电子可以保证内容质量和权威性,其收录的文和报告均来自于经过严格审稿的学术或专业期刊,保证了内容的可信度和专业性。另外,Premier电子拥有较完善的检索和分类系统,用户可以按照自己的需求和兴趣对文进行检索和筛选,从而节省时间和精力。总的来说,Premier电子为学术研究者、商业从业者和爱好者提供了一个高质量、可信、便捷和多样的学习和借鉴资源,有助于推动相关领域的发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值