pointer - like classes && functions - like classes

pointer - like classes

pointer-like classes , 像指针行为的类,C++里一般操作指针的操作符有 ->* ,实质上就是类重载了这两个操作符,使得类的行为看起来像指针。一般这种类中都有一个普通的指针。主要分为两种:智能指针和迭代器。

智能指针

为何设计一个类产生的对象要像一个指针,因为你想要它做比指针更多的事情,所以通常这样做出来的东西,又叫做智能指针。

  #pragma once
class share_ptr
{
public:
    T& operator*() const {return *px;}
    T* operator->() const {return px;}
    shared_ptr(T* p): px(p){}
private:
    T* px;
    long* pn;
......
};

1.T* px; px是指向T类型的指针。
2.C++里面的操作符重载是很常见的,且是很重要和强大的。智能指针的这两个写法几乎是固定的。
智能指针都会有这么一个构造函数:
shared_ptr(T* p): px§{}
这个构造函数的参数接受天然的指针,C++的指针。

struct Foo
{
    ......
        void method(void) {......}
};
shared_ptr<Foo> sp(new Foo);
Foo f(*sp);
sp->method();

假设现在写了一个Class,叫做Foo, 要把Foo这种天然的指针(new Foo)包装到这个智能指针里面去,即shared_ptr指针里面。
sp->method(); 智能指针调用method()方法。操作符’->'属于调用操作符重载哦。这句就相当于px->method(). 操作符->作用在指针对象sp上,得到指针对象px。

注意:当sp->method(),首先是调用智能指针里面的‘->’操作符重载。它会返回T* 类型(也就是 Foo *类型)的指针px.但是箭头‘->’只有一个已经被消耗了。当返回px的时候已经没有指针符号了。原来箭头符号有一个特性,那就是箭头作用的结果会将箭头传递下去,这是c++语法规定的!

迭代器

迭代器是STL里面一大组件(【STL】迭代器(iterators)与traits编程),就是要代表容器里面一个元素,因此它也像一个指针,也可以说它是一个智能指针。他比普通的智能指针重载的操作符更多,比如:指针++就是向前移动,– –就是向后移动。++、– –都是智能指针的操作符重载。

在这里插入图片描述
迭代器重重载了 -> 操作符, 返回的是指向节点的数据的地址。
迭代器重载了 * 操作符 , 返回的是指向节点的数据的引用。
在这里插入图片描述

图中红色的圆点代表链表的迭代器,其中必然有一个真正的指针,就是上面的node,它的类型是 link_type ,追溯到上一行,可以看出是一个指针,所以 operator*()就是对node解引用,取得的就是上图中 prev、next、data 显示的内容,后面又接着使用的"."操作符,就是再取取得的node中的内容中的data部分。

functions - like classes

C++中构造的类像函数,首先我们需要清楚函数有哪些特点。函数由返回类型,函数名称,参数(小括号,作用在函数名上)和函数主题组成。小括号内含参数这部分也称作function core operator,函数调用操作符。如果有个东西能接受小括号,那它就是函数function,或者仿函数function-like。

#include <iostream>


using namespace std;

template<class T>
class identity
{
public:
    const T&
        operator() (const T& x) const { return x+1; }
};

void test_function_like_classes()
{
    int a = 100;
    //这儿两个括号, 第一个括号是调用构造函数的括号, 第二个括号才是 operator()
    int b = identity<int>()(a);
    identity<int> ab;
    int c = ab(a);
    std::cout << b << std::endl;
    std::cout << c << std::endl;
}

int main() {
    test_function_like_classes();
	return 0;
}

下面一些标准库种的做法

template <class T1, class T2>
struct pair
{
  T1 first;
  T2 second; //first和second类型不需要一样
  pair() : first(T1()), second(T2()) {}
  pair(const T1& a, const T2& b)
  : first(T1()), second(T2())
......
};
template<class T>
struct identitypublic 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; }
};

上面的三个类中都包括操作符重载operator(),叫做function-like classes。那么由类创建的对象就叫做函数对象functor。这三个类有各自继承类unary_function。C++标准库中的还有其他的仿函数:

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>
{
  bool operator() (const T& x, const T& y) const { return x == y; }
};
 
template<class T>
struct less : public binary_function<T, T, bool>
{
  bool operator() (const T& x, const T& y) const { return x < y; }
};

上面三个类各自继承类binary_function。

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;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值