在C++的类设计中一般会将类设计的像两种情况:
一种是设计的像一个指针,一种是设计的像一个函数
将类设计的像一种指针(Pointer-like-class),通常也叫智能指针。
这么设计的初衷是:希望这个类可以做比普通指针更多的事,具体的会在c++智能指针中分析,本次记录只学习语法。
如果一个类是Pointer-like-class,那么它一定有一个真正的指针。下面从两种Pointer-like-class进行说明:智能指针和迭代器。
智能指针:
template<class T>
class SharedPtr
{
public:
T& operator*() const
{
return *px;
}
T* operator->() const
{
return px;
}
SharedPtr(T* p) : px(p) {}
private:
T* px;
long* pn;
};
struct Foo {
Foo() {}
Foo(int t)
{
data = t;
}
Foo(const Foo& F)
{
data = F.data;
}
int data = 10;
void method()
{
std::cout << "Foo method has been called";
}
};
上述代码写了一个简易的智能指针,它其中真正的指针为:T* px。该类重载了两个操作符:*和->
这是在指针用法上最常见的两种操作符。
重载*操作符:直接返回指针px的指向值T。
重载->操作符:返回指向T的px;
int main()
{
SharedPtr<Foo> ptr(new Foo);
Foo f = *ptr; //拷贝构造
std::cout << f.data << std::endl; //10
ptr->method(); //Foo method has been called
return 0;
}
注:当->作用在ptr上面后,会返回一个px指针,此时->会继续作用在px指针上。(C++编译器就是这么设计的)
迭代器:
迭代器:可以理解为一种智能指针,但是它比一般智能指针要多重载了一些操作符,比如:++和--操作符,这是因为迭代器的设计初衷就是用来遍历的。
下述代码是迭代器的简易版,主要用来说明。
代码中定义了一个双向链表的结点,有next和pre指针以及结点存储的数据data,在迭代器中真正的指针为typedef list_node<T>* node,重载的*和->与智能指针相差不大,++操作符重载方法是修改为当前node中的next指针,然后返回自己(*this)。
template<class T>
struct list_node {
void* next; //后指针
void* pre; //前指针
T data;
list_node(T t)
{
data = t;
}
};
template<class T>
struct list_iterator {
typedef list_iterator<T> self;
typedef list_node<T>* link_type; //真正的指针
link_type node; //表示链表中的一个结点
T& operator*() //重载*操作符
{
return node->data; //返回了Node中data的引用
}
T* operator->() //重载->操作符
{
return &operator *();
}
bool operator==(self n)
{
return n->node == node; //重载++操作符
}
self operator++()
{
node = (link_type)node->next;
return *this;
}
self operator--()
{
node = (link_type)node->pre;
return *this;
}
};