几天以前,我发表了《最简单最实用的C++ GC》。
http://blog.csdn.net/zhanglibin_1222/archive/2009/12/23/5065573.aspx
运用了使用计数和泛型编程的编程技巧,巧妙地实现了C++高效智能指针,也可以称得上C++ SmartPointer 1.0 测试版。
现在这一版是C++ SmartPointer 1.0 正式版了。~O(∩_∩)O~
其中,灵活运用了使用计数,泛型编程,宏和new的编程技巧。
希望读者多多批评,多多指教!
//SmartPointer.h
#ifndef SMART_POINTER_H
#define SMART_POINTER_H
#include <cstdlib>
//类模板:SmartPointer
//功能:智能指针,自动释放内存。
//注意:
//(1). 使用宏GCNew创建对象(SmartPointer<int> pi = GCNew(int, (0));),
// 一定不要使用new(SmartPointer<int> pi = new int (0);//错误!!!)。
//(2). 注意下面这种特殊情况:
//class A
//{
//public:
// void Func0(){}
// void Func1(){SmartPointer<A> pa = this;}
//};
//{
// SmartPointer<A> pa0 = GCNew(A, ());//正确
// pa0->Func0();//正确
// pa0->Func1();//正确
//}
//{
// A * pa = new A ();//正确
// pa->Func0();//正确
// pa->Func1();//错误,用new分配的对象不能用来初始化SmartPointer<T>对象
// delete pa;
//}
template <typename T> class SmartPointer
{
template <typename T> friend class SmartPointer;
public:
SmartPointer(T * ptr = 0)
:ptr_(ptr)
{}
SmartPointer(const SmartPointer & smartPointer)
:ptr_(smartPointer.ptr_)
{++Use();}
template <typename T> SmartPointer(const SmartPointer<T> & smartPointer)
:ptr_(smartPointer.ptr_)
{++Use();}
SmartPointer & operator =(const SmartPointer & smartPointer)
{
++smartPointer.Use();
RemRef();
ptr_ = smartPointer.ptr_;
return *this;
}
template <typename T> SmartPointer & operator =(const SmartPointer<T> & smartPointer)
{
++smartPointer.Use();
RemRef();
ptr_ = smartPointer.ptr_;
return *this;
}
T & operator *() const
{return *ptr_;}
T * operator ->() const
{return ptr_;}
~SmartPointer() throw()
{RemRef();}
private:
void RemRef() const
{
if(0 == --Use())
{
ptr_->~T();
free((char *)(ptr_) - sizeof(unsigned int));
}
}
unsigned int & Use() const
{return *reinterpret_cast<unsigned int *>((char *)(ptr_) - sizeof(unsigned int));}
T * ptr_;
};
#define GCNew(T, P) SmartPointer<T>(new ((new (malloc(sizeof(unsigned int) + sizeof(T))) unsigned int (1)) + 1) T P )
#endif
下面是测试代码:
//Test.cpp(测试代码)
#include "SmartPointer.h"
#include <iostream>
class A
{
public:
A()
{std::cout << "A()" << std::endl;}
A(int i)
{std::cout << "A(int i) " << i << std::endl;}
A(double d)
{std::cout << "A(double d) " << d << std::endl;}
virtual ~A() throw()
{std::cout << "~A()" << std::endl;}
void Func0() const
{std::cout << "Func0" << std::endl;}
void Func1()
{std::cout << "Func1" << std::endl;}
};
class B : public A
{
public:
B()
{std::cout << "B()" << std::endl;}
B(int i)
:A(i)
{std::cout << "B(int i) " << i << std::endl;}
B(double d)
:A(d)
{std::cout << "B(double d) " << d << std::endl;}
~B() throw()
{std::cout << "~B()" << std::endl;}
};
void Test0()
{
std::cout << "******** Test0 ********" << std::endl;
std::cout << "SmartPointer优点:与new一样强大的构造函数调用" << std::endl;
SmartPointer<int> pi = GCNew(int, (0));
SmartPointer<A> pa0 = GCNew(A, );
SmartPointer<A> pa1 = GCNew(A, ());
SmartPointer<A> pa2 = GCNew(A, (0));
SmartPointer<A> pa3 = GCNew(A, (0.0));
}
void Test1()
{
std::cout << "******** Test1 ********" << std::endl;
std::cout << "SmartPointer优点:与内置指针完全一样的默认转换" << std::endl;
SmartPointer<B> pB0 = GCNew(B, ());
SmartPointer<A> pA0 = GCNew(A, ());
std::cout << "指向派生类变量的指针初始化指向基类变量的指针" << std::endl;
SmartPointer<A> pA1 = pB0;
std::cout << "指向变量的指针初始化指向常量(或不可变变量)的指针" << std::endl;
SmartPointer<const A> pA2 = pA0;
std::cout << "指向派生类变量的指针赋值指向基类常量(或不可变变量)的指针" << std::endl;
std::cout << "SmartPointer优点:与内置指针完全一样的函数调用规则" << std::endl;
pA2 = pB0;
pA0->Func0();
pA1->Func1();
pA2->Func0();
//Error!
//pA2->Func1();
}
void Test2()
{
std::cout << "******** Test2 ********" << std::endl;
std::cout << "SmartPointer优点:更加节约空间" << std::endl;
{
std::cout << "及时释放内存" << std::endl;
SmartPointer<B> pb0 = GCNew(B, ());
pb0.~SmartPointer();
SmartPointer<B> pb1 = GCNew(B, (1));
pb1.~SmartPointer();
SmartPointer<B> pb2 = GCNew(B, (2.0));
pb2.~SmartPointer();
}
{
std::cout << "占用更少的栈空间(仅需要和内置指针一样的栈空间)" << std::endl;
SmartPointer<A> pa = GCNew(A, (1.234567));
std::cout << sizeof(pa) << std::endl;
}
}
class C
{
public:
C()
{
//普通的智能指针没有这么强大的功能吧!
SmartPointer<C> pc = this;
std::cout << "C()" << std::endl;
}
~C()
{
std::cout << "~C()" << std::endl;
}
};
void Test3()
{
std::cout << "******** Test2 ********" << std::endl;
std::cout << "与Java,C#中指针一样强大的功能。" << std::endl;
{
std::cout << "永远不用担心内存泄露!" << std::endl;
GCNew(B, (12.34567));
}
{
std::cout << "竟然可以这样用,功能强大吧!" << std::endl;
std::cout << "普通的智能指针会导致二次删除。" << std::endl;
std::cout << "SmartPointer解除了您的后顾之忧。" << std::endl;
SmartPointer<C> pc = GCNew(C, ());
}
}
int main(int argc, char *argv[])
{
Test0();
Test1();
Test2();
Test3();
return 0;
}