吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1316|回复: 1
收起左侧

[C&C++ 转载] 使用智能指针(share_ptr)的一些想法

[复制链接]
hellozl 发表于 2020-4-10 10:01
以下是c++primer 的单词查询程序,书中的程序用到了智能指针,
在学习的过程中,因不明白为何要用智能指针,于是写了一个不用智能指针的版本,
最终,通过两个程序的区别,理解了使用智能指针的原因:
[C++] 纯文本查看 复制代码
#include<map>
#include<vector>
#include<string>
#include<fstream>
#include<sstream>
#include<set>
#include<iostream>
#include<memory>
using namespace std;
using line_no = vector<string>::size_type;
class QueryResult;
class QueryResult
{
	friend ostream& print(ostream&, const QueryResult&);
public:
	QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>>f) :
		sought(s), lines(p), file(f) {};
private:
	string sought;
	shared_ptr<set<line_no>> lines;    //出现的行号
	shared_ptr<vector<string>> file;
};
class TextQuery
	//map<string,set<int>> vector
{
public:
	using line_no = vector<string>::size_type;
	TextQuery(ifstream&);
	QueryResult query(const string&)const;
private:
	shared_ptr<vector<string>> file;
	map<string, shared_ptr<set<line_no>>> wm;
};
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);
	}
}
TextQuery::TextQuery(ifstream& ifs):file(new vector<string>)
{
	string text;
	while (getline(ifs,text))
	{
		file->push_back(text);
		int 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);
		}
	}

}

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;
}
void runQueries(ifstream& ifs)
{
	TextQuery tq(ifs);
	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 ifs(argv[1]);
	if (ifs)
	{
		runQueries(ifs);
	}
	else
	{
		cerr << "ifs error." << endl;
	}
	return 0;
}

不使用智能指针的版本


免费评分

参与人数 1吾爱币 +5 热心值 +1 收起 理由
苏紫方璇 + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| hellozl 发表于 2020-4-10 10:05
不使用智能指针的版本
[C++] 纯文本查看 复制代码
#include<vector>
#include<string>
#include<fstream>
#include<map>
#include<set>
#include<iostream>
#include<sstream>
using namespace std;
using line_no = vector<string>::size_type;
class QueryResult
{
	friend ostream& print(ostream&,const QueryResult&);
public:
	QueryResult(string s, set<line_no> l, vector<string> f) :
		sought(s),lines(l),file(f){ };
private:
	string sought;
	set<line_no> lines;
	vector<string> file;
};

class TextQuery
{
public:
	TextQuery(ifstream&);
	QueryResult query(const string&)const;
private:
	vector<string> file;
	map<string, set<line_no>> wm;
};
TextQuery::TextQuery(ifstream& ifs)
{
	string text;
	while (getline(ifs,text))
	{
		file.push_back(text);
		int n = file.size() - 1;
		istringstream line(text);
		string word;
		while (line>>word)
		{
			auto &lines = wm[word];
			lines.insert(n);

		}
	}
}

QueryResult TextQuery::query(const string& sought) const
{
	auto loc = wm.find(sought);
	if (loc == wm.end())    //如果没有找到给定的单词
	{
		//
		set<line_no> initSet{};
		return QueryResult(sought, initSet, 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;
}
void runQueries(ifstream& ifs)
{
	TextQuery tq(ifs);
	while (true)
	{
		cout << "Enter the word to look for, or Q to quit :" << endl;
		string s;
		if (!(cin >> s) || s == "q")break;
		print(cout, tq.query(s)) << endl;
	}
}
int main(int argc,char*argv[])
{
	ifstream ifs(argv[1]);
	if (ifs)
	{
		runQueries(ifs);
	}
	else
	{
		cerr << "ifs error." << endl;
	}
	return 0;
}


核心在于query函数返回的QueryResult对象是通过拷贝初始化,还是用指针来初始化。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-6 12:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表