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

Regarding definition of dereferencing and member selection operators in smart pointer

本文关键字:成员 引用 选择 运算符 定义 取消 于智能 智能 指针      更新时间:2023-10-16

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

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

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

为什么前者通过引用返回

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

后者由指针返回

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

如果thing是一个类类型,则通过调用operator->,然后将->member应用于其结果来计算。为了支持这一点,它必须返回一个指针或另一个同样重载operator->的类类型。

我可以通过指针进行取消引用运算符返回吗

是的,但这将相当令人困惑,因为它的行为与应用相同的运算符指针不同。您必须说**thing才能访问T

而另一个通过参考返回

不,因为这将打破语言对重载运算符应该如何工作的固有假设,使其无法使用。

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

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->()"的结果产生非指针结果