《C++ Primer》第12章:动态内存

本文探讨了C++中智能指针(shared_ptr, unique_ptr, weak_ptr)的应用及区别,并通过实例展示了如何使用标准库进行文本查询。通过具体代码示例解释了智能指针的引用计数机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

shared_ptr允许多个指针指向同一个对象,unique_ptr独占所指向的对象,用make_shared函数分配动态内存,返回对象的shared_ptr.

程序使用动态内存的原因之一是需要在多个对象间共享数据, 自己直接管理内存的类与使用智能指针的类不同, 它们不能依赖类的对象拷贝、赋值和销毁操作的任何默认定义.

week_ptr是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象。不改变shared_ptr的引用计数。当创建一个week_ptr时,要用一个shared_ptr来初始化它。因为week_ptr对象可能为空,lock函数用来返回一个指向对象的shared_ptr指针。

int main(int argc, char *args[])
{
    shared_ptr<int> q1 = make_shared<int>(42);
    cout << *q1 << endl;
    shared_ptr<string> q2 = make_shared<string>(10, '9');
    cout << *q2 << endl;
    shared_ptr<int> q3 = make_shared<int>();
    cout << *q3 << endl;

    unique_ptr<string> p1(new string("hi"));
    cout << *p1 << endl;
    unique_ptr<string> p2(p1.release());
    cout << *p2 << endl;
    unique_ptr<string> p3(new string("hihi"));
    p2.reset(p3.release());
    cout << *p2 << endl;

    auto r = make_shared<int>(42);
    cout << r.use_count() << endl;
    weak_ptr<int> wp(r);
    cout << r.use_count() << endl;
    auto r2 = wp.lock();
    cout << r2.use_count() << endl;
    r = q1;
    cout << r2.use_count() << endl;

    system("pause");
    return 0;
}


运行结果为

42
9999999999
0
hi
hi
hihi
1
1
2
1

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

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

using namespace std;

class QueryResult;
class TextQuery {
    friend ostream& printFile(ostream& os, const TextQuery& tq);
public:
    using line_no = vector<string>::size_type;
    TextQuery(ifstream&);
    QueryResult query(const string&) const;
    void printFile() const;
private:
    shared_ptr<vector<string>> file;
    map<string, shared_ptr<set<line_no>>> wm;
};

class QueryResult {
friend ostream &print(ostream & os, const QueryResult &qr);
public:
    using line_no = vector<string>::size_type;
    QueryResult(string s, shared_ptr<set<line_no>> l, shared_ptr<vector<string>> f):
        sought(s), lines(l), file(f) {}
private:
    string sought;
    shared_ptr<set<line_no>> lines;
    shared_ptr<vector<string>> file;
};

TextQuery::TextQuery(ifstream& is) : file(new vector<string>)
{
    string text;
    while(getline(is, text)) {
        file->push_back(text);
        int n = file->size() - 1;
        string word;
        istringstream ist(text);
        while (ist >> 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& printFile(ostream& os, const TextQuery& tq)
{
    for (auto str : *tq.file) {
        os << str << endl;
    }
}

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

int main(int argc, char *args[])
{
    ifstream ifs("input.txt");
    TextQuery tq(ifs);
    printFile(cout, tq);
    QueryResult qr = tq.query("banana");
    print(cout, qr);
    system("pause");
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值