C++ Primer 练习 12.19 - 12.22 题

现在 是 第十二章的部分练习:

12.19:

    定义你自己版本的StrBlobPtr,更新StrBlob类,加入恰当的friend声明及begin和end成员了。

    这题 为了方便 我直接写在一个头文件里。

	
//StrBlob.h
#include <iostream>
#include <memory>
#include<stdexcept>
#include <string>
#include <vector>
using std::cout;
using std::endl;
using std::cin;

class StrBlobPtr;

class StrBlob {
	//友元声明
	friend class StrBlobPtr;

public:
	typedef std::vector<std::string>::size_type size_type;

	StrBlob();
	StrBlob(std::initializer_list<std::string> il);


	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }
	void push_back(const std::string &t) {
		data->push_back(t);
	}

	void pop_back();
	std::string & front();
	std::string& back();
	const std::string & front() const;
	const std::string & back() const;

	// begin() 和 end()
	StrBlobPtr begin();
	StrBlobPtr end();

private:

	std::shared_ptr<std::vector<std::string>> data;

	void check(size_type i, const std::string &msg)const;
};

class StrBlobPtr {

public:
	StrBlobPtr() : curr(0) {}
	StrBlobPtr(StrBlob  &a, std::size_t sz = 0)
		: wptr(a.data), curr(sz) {}

	std::string & deref() const;
	StrBlobPtr& incr();

private:
	std::shared_ptr<std::vector<std::string>>
		check(std::size_t, const std::string &) const;

	std::weak_ptr<std::vector<std::string>> wptr;
	std::size_t curr;
};

//strblob 函数外部定义
const std::string & StrBlob::front() const
{
	check(0, "out range");
	return this->data->front();
}
const std::string &StrBlob::back() const
{
	check(0, "out range");
	return data->back();
}

StrBlob::StrBlob() :data(std::make_shared<std::vector<std::string>>()) {}
StrBlob::StrBlob(std::initializer_list < std::string> il) :
	data(std::make_shared<std::vector<std::string>>(il)) {};


void StrBlob::check(size_type i, const std::string &msg)const
{
	if (i >= data->size())
		throw std::out_of_range(msg);
}

std::string &StrBlob::front()
{
	check(0, "front on empty StrBlob");
	return data->front();
}

std::string &StrBlob::back()
{
	check(0, "back on empty StrBlob");
	return data->back();
}

void StrBlob::pop_back()
{
	check(0, "pop_back on empty StrBlob");
	data->pop_back();
}

StrBlobPtr StrBlob::begin()
{
	return StrBlobPtr(*this);
}

StrBlobPtr StrBlob::end()
{
	auto ret = StrBlobPtr(*this, data->size());
	return ret;
}
//strblobptr 函数外部定义

std::shared_ptr<std::vector<std::string>>
StrBlobPtr::check(std::size_t i, const std::string &msg) const
{
	auto ret = wptr.lock();
	if (!ret)
		throw std::runtime_error("unbound StrBlobPtr");

	if (i >= (*ret).size())
		throw std::out_of_range(msg);

	return ret;
}

std::string & StrBlobPtr::deref() const
{
	auto p = check(curr,"dereference past end");
	return (*p)[curr];
}

StrBlobPtr & StrBlobPtr::incr()
{
	check(curr, "increment past end of StrBlobPtr");
	++curr;
	return *this;
}
//主函数
#include "StrBlob.h"

int main(){StrBlob b({ "233","2333","23333" });StrBlobPtr bp(b);bp.incr();cout << bp.deref() << endl;return 0;}


12.20:

编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印处StrBlob中的每个元素。


#include "StrBlob.h"

int main()
{

	ifstream in_file("text.txt");
	StrBlob b;
	string t;
	StrBlobPtr bp(b);
	while (getline(in_file,t))
		b.push_back(t);
	for (size_t i = 0; i != b.size(); i++)
	{
		cout << bp.deref() << endl;
		bp.incr();
	}

	in_file.close();

	return 0;
}

12.21:

也可以这样编写StrBLobPtr的deref成员:

std::string & deref() const

{ return (*check(curr,"dereference pase end"))[curr]; }

你认为那个版本更好?为什么?

原版本是:

std::string & deref()const
{
    auto p = check(curr,"dereference past end");
    return (*p)[curr];
}
很明显,当然是 第一个版本好,显而易见,第一个版本 可读性比较好,第二个版本 咋一看 还不知道 不什么,要理清优先级,然后check返回一个shared_ptr指针再解引用,之后是下标运算获取元素,而第一版则 轻易看出 check 函数返回一个 指针 ,然后返回 解引用的元素。


12.22:

为了能让StrBlobPtr使用const StrBlob,你觉得应该如何修改?定义一个名为ConstStrBlobPtr的类,使其能够指向const StrBlob。

第一个问题 以我的方法就是  直接添加一个 接受 初始值是 const strblob 的构造函数,所以是:

StrBlobPtr(const StrBlob & a, std::size_t sz = 0) :wptr(a.data), curr(sz) {}
直接再 StrBlobPtr 类里 加上这个成员函数。

第二个问题 则是直接定义一个 构造函数 是上面的 构造函数的ConstStrBlobPtr类,是不是错了 ( ̄▽ ̄)" 不知道 不过挺好的。 望指出。

class ConstStrBlobPtr 
{
public:
	ConstStrBlobPtr():curr(0) {}
	ConstStrBlobPtr(const StrBlob & a,size_t i = 0) : w(a.data),curr(i) {}

	string & deref() const;
	ConstStrBlobPtr & incr();
private:
	shared_ptr<vector<string>>  check(size_t, const string &) const;
	weak_ptr<vector<string>> w; //指向一个vector<string>的shared_ptr指针的对象

	size_t curr;
};

string & ConstStrBlobPtr::deref() const
{
	auto p = check(curr,"wocao");
	return (*p)[curr];
}
ConstStrBlobPtr &  ConstStrBlobPtr::incr()
{
	check(curr, "wocaohhh");
	++curr;
	return *this;
}
shared_ptr<vector<string>>  ConstStrBlobPtr::check(size_t i, const string & msg) const
{
	auto pw = w.lock();
	if (!pw)
		throw std::runtime_error("hhhhh");
	if (i >= pw->size())
		throw std::out_of_range("xxxxx");
	return pw;
}
上面 就这样 ,也需要 关联 StrBlob类 作为 友元类,这点应该难不倒你们哈,你们自己搞哈 ,我 就。。。。溜了溜了。


以上,如果错了 ,望大家提出。(+_+)?

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雫和春的故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值