C++之Pointer-Like Classes

    C++中构造的类一般会像两种东西,像指针(称为pointer-like classes,指针类),或者像函数(称为function-like classes,函数类)。一个类被设计成指针,被当作指针来使用,是因为我们想在传统指针的基础上多实现功能,或者说想对指针有更多的控制。常见的指针类有两种:智能指针和迭代器。

    关于智能指针

    C++中常见的智能指针有auto_ptr,scoped_ptr,shared_ptr等等。下面来介绍shared_ptr,智能指针内部一定有一个真正的指针,图示为:


其中,大圆圈表示一个智能指针,里面包含一个真正的指针px,指向实际所指的对象。

     对于智能指针,和传统的指针一样,会使用两种操作符,*解引用(dereference)操作符和->成员访问操作符。在智能指针类中要提供这两种操作符重载operator* ( )和operator-> ( )

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* p;
  long* pn;
...
};

    在智能指针shared_ptr内有一个真正的指针px,指向对象T。下面的代码示范了智能指针的用法:

struct Foo
{
  ...
  void method(void) {...}
};
shared_ptr<Foo> sp(new Foo);//定义了一个指向Foo类型的智能指针
Foo f(*sp);//定义了一个Foo对象,并使用智能指针sp所指的对象来初始化
sp->method();//相当于px->method();

    现在有一个类Foo,第1行产生了一个天然的指针sp,通过调用智能指针的构造函数,我们把天然的指针包装在智能指针内。第2行当我们解引用*sp,就相当于return *px。第3行sp->method();的意思是想通过智能指针sp调用成员函数method,首先会调用操作符重载operator->( ) const,得到智能指针内部真正的指针px,然后再通过px调用函数method(px->method();)。在C++中规定,对于调用->操作符之后,->操作符并不会消耗掉,而是继续作用下去。

    关于迭代器

    迭代器指向容器中的元素,可以被看做智能指针。不过迭代器除了要提供*和->操作外,还要提供++,--(用于指针移动,可以遍历容器),==和!=操作。下面的代码以链表的迭代器为例:

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 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; }
  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; }
};

    链表的数据结构如图所示:


    链表的节点包含三个部分,分别是前一个节点的指针prev,后一个节点的指针next,和数据data。图示中的“大泡泡”表示迭代器_list_iterator,其中包含一个真实的指针node,用来指向链表中的节点。从程序中可以看到,_list_iterator除了提供*和->操作,还提供了++,--操作。对迭代器进行++操作,会指向下一个元素,对迭代器进行--操作,会指向前一个元素。由于node只是指向整个节点,为了取得节点的数据,还需要调用(*node).data

    _list_iterator的使用示例代码如下:

struct Foo
{
  void method()
  { cout << "method" << endl; }
};

ll::_list_iterator<Foo, Foo&, Foo*> iter;
*iter; //获得一个Foo对象
iter->method(); //意思是调用Foo::method(),相当于(*iter).method,也相当于(&(*iter))->method()
    首先,我们声明一个_list_iterator迭代器iter。我们知道迭代器也是一种指针类,可以模拟指针的操作。通过*操作符,我们可以得到一个Foo对象。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Harr-like是一种用于目标检测的特征描述符。在C++中,可以使用OpenCV库来实现Harr-like特征的使用和训练。引用\[1\]中的代码展示了如何使用OpenCV库加载和保存Harr-like分类器。首先,需要使用cvLoadHaarClassifierCascade函数加载已经训练好的分类器。然后,可以使用cvSave函数将分类器保存到指定的文件中。 引用\[2\]中的代码展示了如何使用Harr-like分类器进行目标检测。首先,需要使用CascadeClassifier类创建一个分类器对象,并使用load函数加载训练好的分类器文件。然后,可以使用detectMultiScale函数对待检测的图像进行人脸检测。检测结果保存在一个矩形容器中,可以通过遍历容器来获取每个检测到的人脸位置,并使用rectangle函数在图像上绘制矩形框来标记人脸位置。 如果想要训练自己的Harr-like分类器,可以使用OpenCV提供的工具。引用\[3\]中的命令展示了如何使用opencv_createsamplesd.exe和opencv_haartrainingd.exe来进行训练。首先,使用opencv_createsamplesd.exe生成正样本文件pos.vec,然后使用opencv_haartrainingd.exe进行训练,生成xml文件。训练过程可能需要一段时间,可以根据实际情况进行等待或强制结束。 总结起来,Harr-like是一种用于目标检测的特征描述符,在C++中可以使用OpenCV库进行加载、保存和使用。同时,OpenCV还提供了工具来训练自己的Harr-like分类器。 #### 引用[.reference_title] - *1* *2* *3* [opencv实现自己训练的Adaboost(Haar-like)检测识别库](https://blog.csdn.net/OEMT_301/article/details/78776159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值