您的位置:首页 > 编程语言 > C语言/C++

C++ 之 智能指针实现

2017-08-10 14:03 267 查看
面试的时候,被问到了智能指针,之前的确看过C++ primer,然而,都忘掉了。。

。。自己实现了一下share_ptr。。写完以后翻了翻书,才发现,和书上的并不差多少。。


智能指针类型: share_ptr, weak_ptr, unique_ptr

template <typename T> class smartPtr
{
public:
smartPtr() :ptr(new T(0)), ptrCount(new int(1)) // 任何构造方式都能调用*p,不会出错,如果初始化为nullptr,调用*p会出错
{
cout <<"empty smart pointer construct ing ~~" <<endl;
}
smartPtr(const T t) :ptr(new T(t)), ptrCount(new int(1))
{
cout<<"smart pointer construct ing ~~"<<endl;
}
smartPtr(smartPtr &rhs) : ptr(rhs.ptr), ptrCount(&(++(*rhs.ptrCount))) //拷贝构造
{
cout<<"smart pointer copy construct ing~~"<<endl;
}
T& operator*()
{
//cout << "operator * is called" << endl;
return *ptr;
}
T* operator->()
{
//cout << "operator -> is called" << endl;
return &(operator *()); // c++ primer 504p, 委托给解引用运算符
}
int getCount()
{
return *( ptrCount);
}
smartPtr& operator=(smartPtr &rhs) //赋值运算符
{
//cout << "operator = is called" << endl;
(*( ptrCount))--;
(*(rhs.ptrCount))++;
if ((*ptrCount) == 0)
{
delete ptr;
delete ptrCount;
ptr = nullptr;
ptrCount = nullptr;
}
ptr = rhs.ptr;
ptrCount = rhs.ptrCount;
return *this;
}
~smartPtr()
{
cout << "destructor is called, count is "<<*( ptrCount) << endl;
if (--*ptrCount == 0)
{
delete ptr;
ptr = nullptr;
}
}
private:
int *ptrCount;
T * ptr;
};
用到的知识点

1. 模板,模板可以扩大传入参数的类型范围 比如,基本类型,int, double, string..这些应该都没什么问题,其他更复杂的类类型,可能需要定义一下 << 运算符

2. 运算符重载,根据share_ptr的特性,要有一个计数器,这样就必须重载 = (赋值运算符)。还有 * (解引用) 和 -->(成员访问)。 计数器的其他实现方法,可以参考(http://blog.csdn.net/hackbuteer1/article/details/7561235)

3. 构造函数,拷贝构造函数

4. 计数器,用指针类型,方便共享

测试例子:

int main(int argc,char *argv[])
{
smartPtr<int> p(42);
smartPtr<int> q;
smartPtr<int> r(p); //copy initialize
cout << "p = " << *p << "; q = " << *q << endl;
cout << "p count " << p.getCount() << "; q count " << q.getCount() << endl;
q = p;
cout << "after q=p q is " << *q << endl;
cout << "p count " << p.getCount() << "; q count " << q.getCount() << endl;
}结果:



正常测试效果看起来还可以,不知道有没有和我一样暴力的程序员,会写:

smartPtr<int> p=*(new smartPtr<int>(40));
这样的代码。 由于在new里面调用了一次构造函数,使得count多出了1,而无法正确释放。( new运算符 1. 返回一片raw空间  2. 调用构造函数 3. 返回指针 )

运行效果,如下: 


如果有解决这个问题的方法,还望不吝赐教~~

菜鸟一枚,如果有错误,请留下您的高见~~Thanks~~ 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息