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 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; }
};
上面的三个类中都包括操作符重载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;
};