C++ Primer(第五版)16.1.6节练习

16.28   重新定义未SP和UP两个模板:

#ifndef SP_H
#define SP_H

#include <iostream>
using namespace std;

template <typename T> 
class SP {
public:
	SP(): p(nullptr), use(nullptr) { }
	explicit SP(T *pt): p(pt), use(new size_t(1)) { }
	SP(const SP &sp): p(sp.p), use(sp.use) { if (use) ++*use; }
	SP& operator=(const SP&);
	~SP();
	T& operator*() { return *p; }
	T& operator*() const { return *p; }
private:
	T *p;
	size_t *use;
};

template <typename T>
SP<T>& SP<T>::operator=(const SP &rhs)
{
	if (use) {
		--*use;
		if (*use == 0) {
			delete p;
			delete use;
		}
	}
	if (rhs.use)
		++*rhs.use;
	
	p = rhs.p;
	use = rhs.use;
	
	return *this;
}

template <typename T>
SP<T>::~SP()
{
	if (use) {
		--*use;
		if (*use == 0) {
			delete p;
			delete use;
		}
	}
}

template <typename T, class... Args>
SP<T> make_SP(Args&&... args)
{
    return SP<T>(new T(std::forward<Args>(args)...));
}

template <typename T>
class UP {
public:
	UP(): p(nullptr) { }
	UP(const UP &up) = delete;
	explicit UP(T* pt) : p(pt) {}  
    UP& operator=(const UP&) = delete;  
    ~UP();
    T* release();   
    void reset(T *new_p);     
    T& operator*() { return *p; }       
    T& operator*() const { return *p; } 
	
private:
	T *p;
};

template <typename T>
UP<T>::~UP()
{
	if (p)
		delete p;
}

template <typename T>
T* UP<T>::release()
{
	T *q = p;
    p = nullptr; 
    return q; 	
}

template <typename T>
void UP<T>::reset(T *new_p)
{
	auto temp = new_p;
	if (p)
		delete p;
	p = temp;
}

#endif

16.29    重新修改Blob模板:

#ifndef	BLOB_H
#define	BLOB_H

#include <iostream>
#include <vector>
#include <stdexcept>
#include <memory>
#include "sp.h"

using namespace std;

template <typename> class BlobPtr;

template <typename T> class Blob {
	friend class BlobPtr<T>;
public:
	typedef typename vector<T>::size_type size_type;
	Blob();
	Blob(initializer_list<T> il);
	size_type size() const { return (*data).size(); }
	bool empty() const { return (*data).empty(); }
	void push_back(const T &t) { (*data).push_back(t); }
	void push_back(T &&t) { (*data).push_back(std::move(t)); }
	void pop_back();
	T& front();
	T& back();
	T& operator[](size_type i);
	const T& front() const;
	const T& back() const;
	const T& at(size_type) const;
	const T& operator[](size_type i) const;
private:
	SP<vector<T>> data;
	void check(size_type i, const string &msg) const;
};

template <typename T>
void Blob<T>::check(size_type i, const string &msg) const
{
	if (i >= (*data).size())
		throw out_of_range(msg);
}

template <typename T>
Blob<T>::Blob(): data(make_SP<vector<T>>()) { }

template <typename T>
Blob<T>::Blob(initializer_list<T> il): 
			data(make_SP<vector<T>>(il)) { }
			
template <typename T>
void Blob<T>::pop_back()
{
	check(0, "pop back on empty Blob");
	(*data).pop_back();
}

template <typename T>
T& Blob<T>::front()
{
	check(0, "front on empty Blob");
	return (*data).front();
}

template <typename T>
T& Blob<T>::back()
{
	check(0, "back on empty Blob");
	return (*data).back();
}

template <typename T>
T& Blob<T>::operator[](size_type i)
{
	check(i, "subscritpt out of range");
	return (*data)[i];
}

template <typename T>
const T& Blob<T>::front() const 
{
	check(0, "front on empty Blob");
	return (*data).front();
}

template <typename T>
const T& Blob<T>::back() const
{
	check(0, "back on empty Blob");
	return (*data).back();
}

template <typename T>
const T& Blob<T>::operator[](size_type i) const
{
	check(i, "subscritpt out of range");
	return (*data)[i];
}

template <typename T>
const T& Blob<T>::at(size_type i) const
{
	check(i, "subscritpt out of range");
	return (*data).at(i);
}

#endif

16.30    测试主程序:

#include <string>
#include <iostream>
#include <vector>
#include "sp_blob.h"

using namespace std;

int main()
{
	Blob<string> b1; // empty Blob
	cout << b1.size() << endl;

	{  // new scope
		Blob<string> b2 = {"a", "an", "the"};
		b1 = b2;  // b1 and b2 share the same elements
		b2.push_back("about");
		cout << b1.size() << " " << b2.size() << endl;
	} // b2 is destroyed, but the elements it points to must not be destroyed
	cout << b1.size() << endl;


	for(size_t i = 0; i < b1.size(); ++i)
    {
		cout << b1.at(i) << " ";
    }
    cout << endl << endl;

    UP<int> u1(new int(42));
    cout << *u1 << endl;
    UP<int> u2(u1.release());
    cout << *u2 << endl;

	return 0;
}

16.31    shared_ptr在运行时绑定删除器,unique_ptr在编译时绑定删除器。对unique_ptr而言,删除器类型是unique_ptr类型的一部分。通过这种方式,unique_ptr避免了间接调用删除器的开销,还可以将自定义的删除器(DebugDelete)编译为内联形式。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值