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;
}