C++学习12:类的行为

类的行为分为行为像指针的类和行为像函数的类。它是指一个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++标准库》。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值