• 模板学习实践二 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();
    	}
    

      

  • 相关阅读:
    [转]char、varchar、nchar、nvarchar的区别
    【转】Asp.net 2.0中页的生存周期(Lifecycle)和动态控件 [.Net]
    git免登录sshkey
    ios8,xcode6 周边
    iOS 推送证书
    Lazarus中TreeView导出XML以及XML导入TreeView
    flac文件提取专辑封面手记
    Lazarus解决含中文文件名或路径的使用问题
    使用PowerShell管理Windows8应用
    thbgm拆包【in progress】
  • 原文地址:https://www.cnblogs.com/itdef/p/5744544.html
Copyright © 2020-2023  润新知