模板学习实践二 pointer

c++ template学习记录

使用模板将实际类型的指针进行封装

当变量退出作用域 自动delete

// 1111.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

template <typename T>
class Holder {
private:
	T* ptr;    // refers to the object it holds (if any)

public:
	// default constructor: let the holder refer to nothing
	Holder() : ptr(0) {
	}

	// constructor for a pointer: let the holder refer to where the pointer refers
	explicit Holder(T* p) : ptr(p) {
	}

	// destructor: releases the object to which it refers (if any)
	~Holder() {
		delete ptr;
	}

	// assignment of new pointer
	Holder<T>& operator= (T* p) {
		delete ptr;
		ptr = p;
		return *this;
	}

	// pointer operators
	T& operator* () const {
		return *ptr;
	}

	T* operator-> () const {
		return ptr;
	}

	// get referenced object (if any)
	T* get() const {
		return ptr;
	}

	// release ownership of referenced object
	void release() {
		ptr = 0;
	}

	// exchange ownership with other holder
	void exchange_with(Holder<T>& h) {
		std::swap(ptr, h.ptr);
	}

	// exchange ownership with other pointer
	void exchange_with(T*& p) {
		std::swap(ptr, p);
	}

private:
	// no copying and copy assignment allowed
	Holder(Holder<T> const&);
	Holder<T>& operator= (Holder<T> const&);
};

class Something {
public:
	void perform() const {
	}
};

void do_two_things()
{
	Holder<Something> first(new Something);
	first->perform();

	Holder<Something> second(new Something);
	second->perform();
}

int main()
{
	do_two_things();
}

  

// 1111111.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stddef.h>
#include <iostream>
#include <vector>

using namespace std;

size_t* alloc_counter()
{
	return ::new size_t;
}

void dealloc_counter(size_t* ptr)
{
	::delete ptr;
}

class SimpleReferenceCount {
private:
	size_t* counter;    // the allocated counter
public:
	SimpleReferenceCount() {
		counter = NULL;
	}

	// default copy constructor and copy-assignment operator
	// are fine in that they just copy the shared counter

public:
	// allocate the counter and initialize its value to one:
	template<typename T> void init(T*) {
		counter = alloc_counter();
		*counter = 1;
	}

	// dispose of the counter:
	template<typename T> void dispose(T*) {
		dealloc_counter(counter);
	}

	// increment by one:
	template<typename T> void increment(T*) {
		++*counter;
	}

	// decrement by one:
	template<typename T> void decrement(T*) {
		--*counter;
	}

	// test for zero:
	template<typename T> bool is_zero(T*) {
		return *counter == 0;
	}
};

class StandardArrayPolicy {
public:
	template<typename T> void dispose(T* array) {
		delete[] array;
	}
};

class StandardObjectPolicy {
public:
	template<typename T> void dispose(T* object) {
		delete object;
	}
};

template<typename T,
	typename CounterPolicy = SimpleReferenceCount,
	typename ObjectPolicy = StandardObjectPolicy>
	class CountingPtr : private CounterPolicy, private ObjectPolicy {
	private:
		// shortcuts:
		typedef CounterPolicy CP;
		typedef ObjectPolicy  OP;

		T* object_pointed_to;      // the object referred to (or NULL if none)

	public:
		// default constructor (no explicit initialization):
		CountingPtr() {
			this->object_pointed_to = NULL;
		}

		// a converting constructor (from a built-in pointer):
		explicit CountingPtr(T* p) {
			this->init(p);         // init with ordinary pointer
		}

		// copy constructor:
		CountingPtr(CountingPtr<T, CP, OP> const& cp)
			: CP((CP const&)cp),      // copy policies
			OP((OP const&)cp) {
			this->attach(cp);      // copy pointer and increment counter
		}

		// destructor:
		~CountingPtr() {
			this->detach();        // decrement counter
								   //  (and dispose counter if last owner)
		}

		// assignment of a built-in pointer
		CountingPtr<T, CP, OP>& operator= (T* p) {
			// no counting pointer should point to *p yet:
			assert(p != this->object_pointed_to);
			this->detach();        // decrement counter
								   //  (and dispose counter if last owner)
			this->init(p);         // init with ordinary pointer
			return *this;
		}

		// copy assignment (beware of self-assignment):
		CountingPtr<T, CP, OP>&
			operator= (CountingPtr<T, CP, OP> const& cp) {
			if (this->object_pointed_to != cp.object_pointed_to) {
				this->detach();    // decrement counter
								   //  (and dispose counter if last owner)
				CP::operator=((CP const&)cp);  // assign policies
				OP::operator=((OP const&)cp);
				this->attach(cp);  // copy pointer and increment counter
			}
			return *this;
		}

		// the operators that make this a smart pointer:
		T* operator-> () const {
			return this->object_pointed_to;
		}

		T& operator* () const {
			return *this->object_pointed_to;
		}

		// additional interfaces will be added later
		//...

	private:
		// helpers:
		// - init with ordinary pointer (if any)
		void init(T* p) {
			if (p != NULL) {
				CounterPolicy::init(p);
			}
			this->object_pointed_to = p;
		}

		// - copy pointer and increment counter (if any)
		void attach(CountingPtr<T, CP, OP> const& cp) {
			this->object_pointed_to = cp.object_pointed_to;
			if (cp.object_pointed_to != NULL) {
				CounterPolicy::increment(cp.object_pointed_to);
			}
		}

		// - decrement counter (and dispose counter if last owner)
		void detach() {
			if (this->object_pointed_to != NULL) {
				CounterPolicy::decrement(this->object_pointed_to);
				if (CounterPolicy::is_zero(this->object_pointed_to)) {
					// dispose counter, if necessary:
					CounterPolicy::dispose(this->object_pointed_to);
					// use object policy to dispose the object pointed to:
					ObjectPolicy::dispose(this->object_pointed_to);
				}
			}
		}
};


	void test1()
	{
		std::cout << "\ntest1():\n";
		CountingPtr<int> p0;
		{
			CountingPtr<int> p1(new int(42));
			std::cout << "*p1: " << *p1 << std::endl;

			*p1 = 17;
			std::cout << "*p1: " << *p1 << std::endl;

			CountingPtr<int> p2 = p1;
			std::cout << "*p2: " << *p2 << std::endl;

			*p1 = 33;
			std::cout << "*p2: " << *p2 << std::endl;

			p0 = p2;
			std::cout << "*p0: " << *p0 << std::endl;

			++*p0;
			++*p1;
			++*p2;
			std::cout << "*p0: " << *p0 << std::endl;
			std::cout << "*p1: " << *p1 << std::endl;
			std::cout << "*p2: " << *p2 << std::endl;
		}
		std::cout << "after block: *p0: " << *p0 << std::endl;
	}

	void test2()
	{
		std::cout << "\ntest2():\n";
		{ CountingPtr<int> p0(new int(42));
		CountingPtr<int> p2 = p0;
		}
		CountingPtr<int> p1(new int(42));

		std::cout << "qqq" << std::endl;

		std::vector<CountingPtr<int> > coll;
		std::cout << "qqq" << std::endl;
		coll.push_back(p1);
		std::cout << "qqq" << std::endl;
		coll.push_back(p1);
		std::cout << "qqq" << std::endl;

		std::cout << "qqq" << std::endl;

		++*p1;
		++*coll[0];
		std::cout << *coll[1] << std::endl;
	}


	int main()
	{
		test1();
		test2();
	}

  

posted on 2016-08-06 17:40  itdef  阅读(373)  评论(0编辑  收藏  举报

导航