当使用Smart Pointer来代替C++的自建指针的时候,应当特别注意处理构造和析构函数,赋值和复制构造函数,解引用函数。
通常的智能指针的写法为:
<script src="https://code.csdn.net/snippets/490333.js"></script>
智能指针的构造、赋值、析构
智能指针的构造函数传递的形参必须是动态创建的指针。在这里尝试使用auto_ptr来举例子,auto_ptr类似一个简易的智能指针,智能指针的一个需要解决的问题是在进行赋值,或进行复制的时候应当如何处理,auto_ptr的处理方式是进行指针的使用权的交替,指向这个变量的指针一直只有一个,这样就可以保证在进行析构的时候不会出错。下面是AutoInstruction的默认构造函数,复制构造函数和赋值操作符:
<script src="https://code.csdn.net/snippets/490363.js"></script>
使用auto_ptr作为一个函数的形参应当进行引用传递而不应当是值传递,因为进行值传递的时候会调用拷贝构造函数,这样会使指针的使用权替换,而在函数结束的时候调用析构函数。所有使用auto_ptr的对象作为形参传递的时候应当使用值传递。
实现解引用操作符
解引用操作符包括了operator* 和 operator->函数,其中operator*应当返回的值应当是引用而不应当是对象,这样就可以方便多态的使用,因为在智能指针中的pointee指向的对象不一定是T也有可能是T的派生对象,如果返回的是对象就会出错,而且返回为对象会降低效率。
以上所讨论的是若你想创建一个智能指针应当首先从这几个方面来进行编写,这是一个编写智能的基本函数,而下面将要列出的一些使用方法并非每一个智能指针都会使用到的,应当具体情况具体分析。
测试Smart Pointers 是否为空
测试智能指针是否为空的第一个方法是将智能指针进行隐式类型转换,将对象中的C++自建指针转换为void* 并在进行比较,使用的函数为:
template<class T>
SmartPointer::operator void*()
{return static_cast<void*> pointee;}
使用这个方法就可以调用SmartPointer<int> ptn(new int(5)); if(ptn == 0){},这样就不会出错了,但是对于对象进行隐式类型转换会带来很多危险,详细内容请看More Effective C++的条款5.
另一种方式是使用operator!!函数,类的声明如下:
<script src="https://code.csdn.net/snippets/490404.js"></script>
这样就可以在通过if( !ptn )来进行判断了。
将Smart Pointer 转换为 C++自建指针
会出现这种情况的原因是有一些函数是不支持SmartPointer的,这里就必须将其转化为C++内建指针。
不要为C++内建指针提供隐式类型转换,除非不得已
Smart Pointer 和 “与继承有关的” 类型转换
两种方式
在这里使用的是member template function,即为成员模板函数