【C++ Primer 习题集】(第5版)练习12.19:定义你自己版本的StrBlobPtr,更新StrBlob类,加入恰当的friend声明及begin和end成员。

【C++ Primer 习题集】(第5版)
练习12.19:定义你自己版本的StrBlobPtr,更新StrBlob类,加入恰当的friend声明及begin和end成员。
StrBlob是一个用于存储字符串类的变长容器,在访问、尾部添加、尾部删除时带有下标越界检查。StrBlob与自定义的指针类StrBlobPtr配合使用,来完成常见的容器操作。
参考代码:

#include<algorithm>
#include<string>
#include<vector>
#include<initializer_list>
#include<memory>
#include<stdexcept>
#include<iostream>
#pragma warning(disable:4996)
using std::string; using std::vector; using std::make_shared; using std::shared_ptr; using std::weak_ptr; using std::size_t;
using std::initializer_list; using std::out_of_range; using std::runtime_error; using std::cin; using std::cout; using std::endl;
class StrBlob {
	friend class StrBlobPtr;
public://公有成员
	StrBlob() { data = make_shared<vector<string>>(); }//参数为空的构造函数
	StrBlob(const initializer_list<string>& i) { data = make_shared<vector<string>>(i); }//包含一个initializer_list作参数的构造函数
	size_t size() const { return data->size(); }//返回已存储字符串数量的大小。
	bool empty() const { return data->empty(); }//返回容器是否为空
	string& front() const { return data->front(); }//返回容器最前端的字符串
	string& back() const { return data->back(); }//返回容器最后端的字符串
	void emplace_back(const string& s) { data->emplace_back(s); }//在尾部放入新字符串(C++11起)
	void push_back(const string& s) { data->push_back(s); }//在尾部放入新字符串
	void pop_back() { check_oor(0, "ERROR: Popping back on an empty StrBlob."); data->pop_back(); }//弹出(删除)最尾端的字符串
	void clear() { data->clear(); }//清除全部已存储的字符串
	bool operator==(const StrBlob& b) { return *this->data == *b.data; }//重定义==运算符,以便能够通过==方便地判断两个StrBlob是否相等
	string& operator[](const size_t& n) { check_oor(n, "ERROR: Subscript out of range."); return (*data)[n]; }//重定义[]运算符,以便能够像访问数组一样访问每个保存的字符串。返回非常量时,允许通过该运算符赋值。
	const string& operator[](const size_t& n) const { check_oor(n, "ERROR: Subscript out of range."); return (*data)[n]; }重定义[]运算符,以便能够像访问数组一样访问每个保存的字符串
	shared_ptr<vector<string>>& address() { return data; }
private://私有成员
	shared_ptr<vector<string>> data;//数据存储区域(指针)
	void check_oor(const size_t& s, const string& msg) const { if (s >= data->size())throw out_of_range(msg); }//检查下标是否越界,如果是则抛出错误
};
class StrBlobPtr {
public:
	StrBlobPtr() {};//构造函数
	StrBlobPtr(const StrBlob& s) { p = s.data; };//构造函数
	StrBlobPtr(const shared_ptr<vector<string>>& s) { p = s; }//构造函数
	void point_to(const StrBlob& s) { p = s.data; }//改变StrBlobPtr指向的StrBlob对象
	void point_to(const shared_ptr<vector<string>>& s) { p = s; }//改变StrBlobPtr指向的StrBlob对象
	vector<string>& operator*() const { check_notnull("The StrBlobPtr points to no objects."); return *p.lock(); }//重定义*运算符,可通过该运算符直接对指向的StrBlob的用于存储字符串的vector进行操作
	shared_ptr<vector<string>> operator->() const { check_notnull("The StrBlobPtr points to no objects."); return p.lock(); }//重定义*运算符,可通过该运算符直接对指向的StrBlob的用于存储字符串的vector进行操作
private:
	weak_ptr<vector<string>> p;//指针,用于指向StrBlob的data私有对象
	void check_notnull(const string& msg) const { if (p.expired())throw runtime_error(msg); }//检查指向的对象是否已销毁
};
int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0);
	StrBlob b1, b2, b3;
	b1.emplace_back("sin"), b1.emplace_back("cos"), b1.emplace_back("tan");
	cout << b1[0] << ' ' << b1[1] << ' ' << b1[2] << '\n';
	b1[0] = "SIN"; cout << b1[0] << '\n'; b1[0] = "sin";
	b2 = b1; cout << b2[0] << ' ' << b2[1] << ' ' << b2[2] << '\n';
	b2.emplace_back("cot"), b2.emplace_back("sec"), b2.emplace_back("csc");
	cout << b1[0] << ' ' << b1[1] << ' ' << b1[2] << ' ' << b1[3] << ' ' << b1[4] << ' ' << b1[5] << '\n';
	cout << (b1 == b3) << '\n';
	StrBlobPtr p(b1);
	cout << (*p).front() << '\n';
	p = b3.address(); cout << (*p).empty() << '\n';
	p.point_to(b2); cout << p->back() << endl;
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值