类的行为分为行为像指针的类和行为像函数的类。它是指一个class创建出来,有可能让它像一个指针,也有可能让他像一个函数。
先放结论:
有重载 operator*和operator-> 的类为行为像指针的类(pointer-like classes)
有重载 operator() 的类为行为像函数的类(function-like classes)
1 pointer-like classes
指针所允许的动作,这个class的对象也应该也都要能够允许,所以需要这个class能够完成指针两个基本操作:*和->。
1.1 智能指针
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;
...
};
使用方法:
struct Foo //一个类型
{
...
void method(void) {......}
};
shared_ptr<Foo> sp(new Foo);//把 Foo这个类型经过构造函数包装成智能指针 sp指向的
Foo f(*sp); //创建一个 Foo类型的值,初始化这个值为sp指向的值,调用上方的operator*()函数
sp->method(); //等同于*sp.method(),上面看到这里返回px,也等同于上方的px->method()
1.2 迭代器
迭代器:用于指向容器中的元素,主要用于遍历。(有点像智能指针)
下面的代码主要看操作符重载operator*()和operator->()。
template<class T>
struct __list_node
{
void* prev;
void* next;
T data;
};
template<class T, class Ref, class Ptr>
struct __list_iterator
{
typedef __list_iterator<T, Ref, Ptr> self;
typedef Ptr pointer;
typedef Ref reference;
typedef __list_node<T>* link_type;//可知:link_type是一个指向list_node<T>类型的指针
link_type node;
bool operator==(const self& x) const {return node == x.node; }
bool operator!=(const self& x) const { return node != x.node; }
reference operator*() const { return {*node}.data; }//做*操作,即取此节点的data
pointer operator->() const { return &(operator*());}//做->操作,后面有分析
self& operator++() { node = (link_type)((*node).next); return *this;}
self operator++(int) { self tmp = *this; ++*this; return tmp;}
self& operator--() { node = (link_type)((*node).prev); return *this;}
self operator--(int) { self tmp = *this; --*this; return tmp; }
};
再来具体表现一下->的操作:
list<Foo>::iterator ite;
...
*ite;//获得一个Foo object
ite->method();
//意思是调用Foo::method()
//相当于(*ite).method();
//相当于(&(*ite))->method();
2 function-like classes
2.1 仿函数
目的:一个类的行为像一个函数,也就是能接受小括号(),即含有操作符重载operator()。
template <class T1, class T2>
struct pair
{
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& a, const T2& b): first(a), second(b) {}
......
};//pair类的定义
template <class T>
struct identity
{
const T&
operator() (const T& x) const { return x; } //operator()传出原对儿
};
template <class Pair>//需要接受pair类型
struct select1st
{
const typename Pair::first_type&
operator() (const Pair& x) const
{ return x.first; } //operator()取第一个值
};
template <class Pair>
struct select2nd
{
const typename Pair::second_type&
operator() (const Pair& x) const
{ return x.second; } //operator()取第二个值
};
这种operator()的class称为仿函数。
2.2 扩展
在标准库中,比起上面的形式更为复杂:
template <class T>
struct identity : public unary_function<T, T>
{
const T&
operator() (const T& x) const { return x; }
};
template <class Pair>
struct select1st : public unary_function<Pair, typename Pair::first_type>
{
const typename Pair::first_type&
operator() (const Pair& x) const
{ return x.first; }
};
template <class Pair>
struct select2nd : public unary_function<Pair, typename Pair::second_type>
{
const typename Pair::second_type&
operator() (const Pair& x) const
{ return x.second; }
};
再来看另一种仿函数:
template <class T>
struct plus : public binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const { return x + y; }
};
template <class T>
struct minus : public binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const { return x - y; }
};
template <class T>
struct equal_to : public binary_function<T, T, bool>
{
T operator()(const T& x, const T& y) const { return x == y; }
};
template <class T>
struct plus : public binary_function<T, T, bool>
{
T operator()(const T& x, const T& y) const { return x < y; }
};
他们这些仿函数,都有各自继承的一些奇特的base classes,如下:
template <class Arg, class Result>
struct unary_function
{
typedef Arg argument_type;
typedef Result result_type;
};
template <class Arg1, class Arg2, class Result>
struct binary_function
{
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
这部分扩展内容详见《C++标准库》。