1.智能指针概念,一个class所产生的一个对象,像一个指针。所以叫做pointer-like classes
2.为什么要有智能指针,因为我们都希望有一个比指针功能更多的指针。所以产生了一个智能指针。
在C++2.0之前也就是C++11之前,有智能指针叫做auto pointer,在c++2.0之后,有许多智能指针,例如
shared_ptr。
3.代码例子:
template<class T>
class shared_ptr
{
public:
T& operator*() const { return *px; }
T* operator->() const { return px; }
shared_ptr(T* p) : px(p) { }
private:
T* px;
long* pn;
......
};
所有智能指针都会有一个共同的点就是里面一定会有一个真正的指针。
现在不讨论智能指针到底有多智能,先讨论语法。
那么指针要代表一般的指针,所以得需要operator*()与operator->(),这两种操作符重载写法一般都是固定得。
假如我们有一个Foo
struct Foo
{
...
void method(void) { ....}
};
使用示例:
shared_ptr<Foo> sp(new Foo);
Foo f(*sp);
sp->method(); //等于px->method();
看第二句语句,sp现在就相当于px指针,当我们解引用*sp,就相当于return *px;
再看第三句语句。通过这个智能指针去调用method()这个函数。也就是通过Foo的对象去调用method。
这是使用者希望的,那么智能指针就要去满足这种情况,正如->的操作符重载,就是return px;那就是px->method()
这种转换之后看起来->这个符号好像是消耗掉了,为什么还会有->这个符号在px之后?因为箭头符号有个特殊的
情况就是箭头这个符号会继续作用下去。
4.总结下语法
智能指针中一定要有*与->操作符重载,并且写法与上面的例子中是一样的,写法也是固定的。
5.迭代器也是一种智能指针。
迭代器是容器中指向元素的一种指针。
但是迭代器iterrator除了要操作符重载*与->还需要重载++与--还有很多的操作符重载。
这里举个链表指针的例子;
template<class T, class Ref, class Ptr>
struct __list_iterator
{
typedef __list_iterator<T,Ref,Ptr> self;
typedef Ptr pointer;
typedef Ref reference;
tyupedef __list_node<T>* link_type;
link_type node;
....
reference operator*() const { return (*node).data; }
pointer operator->() const { return &(operator*()); }
....
};
可以看出link_type是一个指针指向一个节点,节点代码:
template<class T>
struct __list_node
{
void* prev;
void* next;
T data;
};
这是一个双向链表,有双向指针与data。
当我们node指向一个节点,那么使用者的*node是什么?就是对node解引用,就是要取值,取这个data。
但是在代码中,*node取得的是一个__list_node里面有prev与next与data,那用户只需要data,那就是取(*node).data
应用示例:
list<Foo>::iterator ite;
...
*ite; //获得一个Foo object
ite->method();
//意思就是调用Foo::method(0
//相当于(*ite).method();
//相当于(&(*ite))->mothod();
最后一段注释就相当于:
pointer operator->() const { return &(operator*()); }