首页 > 社交 > 科普中国

C++|深入理解智能指针

常驻编辑 科普中国 2022-05-27 指针   智能   函数   对象   成员   模板   能力   东西   版本   操作

It’s often the case that you’ll need something that behaves like a pointer, but a built-in pointer type just doesn’t do the job. In those cases, a C++ programmer will use a “smart pointer. ”pTL拜客生活常识网

我们经常遇到这样的情形:需要某种类似指针的东西,但内建的指针又做不了我们想要做的事情。在这些情形下,C++程序员可以使用一个“智能指针” 。pTL拜客生活常识网

A smart pointer is a class type that is tricked up to look and act like a pointer but that provides additional capability beyond that provided by a built-in pointer. Generally, a smart pointer uses the capabilities provided by a class’s constructors, destructor, and copy operations to control access to or keep track of what it points to in a way that a built-in pointer cannot.pTL拜客生活常识网

智能指针是一个类类型,它乔装打扮成一个指针,但额外提供了内建指针所无法提供的能力。通常而言,一个智能指针通过使用类的构造函数、析构函数和复制操作符所提供的能力,来控制(或跟踪)对它所指向的东西的访问,而内建指针在这方面则无能为力。所有智能指针都重载 -> 和* 操作符,从而可以采用标准指针语法来使用它们(一些罕见的智能指针甚至还重载了->* 操作符)。pTL拜客生活常识网

All smart pointers overload the -> and * operators so that they can be used with standard pointer syntax. (Some rare specimens even go so far as to overload the ->* operator; ) Other smart pointers (in particular, smart pointers used as STL iterators) overload other pointer operators, like ++, --, +, -, +=, -=, and []. Smart pointers are often implemented as class templates so that they may refer to different types of objects. Here’s a very simple smart pointer template that performs a check that it’s not null before use:pTL拜客生活常识网

另有一些智能指针(尤其是用作STL迭代器的指针)还重载了其他一些指针操作符,包括++、--、 、-、+=、-=以及[ ]等。智能指针通常采用类模板来实现,从而使它们可以指向不同类型的对象。下面是一个非常简单的智能指针模板,它执行一个检查, 确保在被使用之前不为空:pTL拜客生活常识网

template 
class CheckedPtr {
public:
    explicit CheckedPtr( T *p ) : p_( p ) {}
    ~CheckedPtr() { delete p_; }
    T *operator ->() { return get(); }
    T &operator *() { return *get(); }
private:
    T *p_; // what we're pointing to
    T *get() { // check ptr before returning it
        if( !p_ )
            throw NullCheckedPointer();
        return p_;
    }
    CheckedPtr( const CheckedPtr & );
    CheckedPtr &operator =( const CheckedPtr & );
};

Use of a smart pointer should be straightforward, mimicking the use of a built-in pointer:pTL拜客生活常识网

智能指针的用法非常简单,酷似内建指针的用法:pTL拜客生活常识网

CheckedPtr s( new Circle );
s->draw(); // same as (s.operator ->())->draw()

The key to this facede is the overloaded operator ->. The -> operator must be overloaded as a member and has a rather unusual property in that it is not “consumed” when it is called. In other words, when we write s->draw(), the compiler recognizes that s is not a pointer but a class object with an overloaded operator -> (that is, that s is a smart pointer). This results in a call to the member overloaded operator, which returns (in this case) a Shape * built-in pointer. This pointer is then used to call Shape’s draw function. If you write this out longhand, you’ll get the following challenging expression: (s. operator ->())->draw(), which contains two uses of the -> operator, one overloaded, one built in.pTL拜客生活常识网

在这个用法外表之下的关键点在于重载的operator->, 此操作符必须被重载为一个成员函数,并且具有一个非同寻常的性质,即当它被调用时,它并不被消耗掉(consumed),换句话说, 当我们写s->draw()时, 编译器识别出s不是一个指针, 而是一个重载了operator->的类对象(即s是一个智能指针)。这将导致对成员重载的操作符的调用,本例中返回一个Shape*内建指针。然后该指针被用于调用Shape的draw函数。如果采用普通写法来编写代码,将会得到如下具有挑战性的表达式(s.operator->())->draw(), 其中包含了两个->操作符,一个是重载的版本,另一个是内建的版本。

相关阅读:

  • 指针怎么用 c语言指针与一维数组?
  • ABB机器人Compact
  • 现在万用表使用非常广泛,但不知道怎么弄,有什么好方法?
  • 单片机时间片轮询任务调度的实现方法
  • 大一想参加学校机器人设计比赛,已经组好队,要学习单片机
  • 回调函数最简单的理解方式
  • 精工5
  • 2022年上半年推出的那些优秀的飞行员手表作品
  • 家乡异地皆乐趣:浪琴Spirit
  • 跟随布拉格天文钟,窥探600年前星空的秘密
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。