关于智能指针中解除引用和成员选择运算符的定义

时间:2015-04-03 14:23:29

标签: c++ operator-overloading smart-pointers dereference

在智能指针实现中,取消引用运算符和成员选择运算符始终定义如下。

T& operator* () const     // dereferencing operator
{
    return *(m_pRawPointer); 
}

T* operator->() const     // member selection operator
{
    return m_pRowPointer;
}

我不太明白为什么前者是通过引用返回的,后者是由指针返回的。是仅仅区分它们还是其他一些原因? 更具体地说,我可以通过指针进行解除引用操作符返回,而另一个通过引用返回吗?

2 个答案:

答案 0 :(得分:1)

  

为什么前者通过引用返回

因此表达式*thing给出一个左值表示T类型的对象,就像thing是一个指针一样。

  

后者由指针

返回

因为这是指定语言的方式。请注意,您永远不会直接使用->的结果,但始终使用thing->member形式的表达式。

如果thing是类类型,则通过调用operator->进行评估,然后将->member应用于结果。为了支持它,它必须返回一个指针或另一个类型,它也会重载operator->

  

我可以通过指针

进行解除引用操作符返回

是的,但这会让人感到困惑,因为它对于将同一个操作符应用于指针的行为会有所不同。您必须说**thing才能访问T

  

而另一个通过引用返回

不,因为这会破坏语言关于重载运算符应如何工作的内置假设,使其无法使用。

答案 1 :(得分:0)

取消引用运算符通过引用返回并且成员选择运算符通过指针返回的原因是将使用智能指针的语法与使用原始指针的语法对齐:

int* p = new int(42);
*p = 7;

std::unique_ptr<int> p(new int(42));
*p = 7;

你绝对可以让你的解引用操作符返回你喜欢的任何内容:

struct IntPtr {
    int* p;

    int* operator*() { return p; }
};

但是当他们不得不写下来时,这对你的用户来说会非常混乱:

IntPtr p{new int{42}};
**p = 7;

箭头操作符与[over.ref]有点不同:

  

表达式x->m被解释为(x.operator->())->m

所以你必须返回一些你可以调用->m的东西,否则你只会得到一个错误(来自gcc):

  

错误:'operator-&gt;()'的结果产生非指针结果