C++重载解引用运算符

use*_*777 31 c++

我对C++比较陌生,仍然试图掌握语法.我一直在看一些运算符重载的例子,最近的智能指针实现.这是我正在看的一个非常通用的例子:

template < typename T > class SP
{
    private:
    T*    pData; // Generic pointer to be stored
    public:
    SP(T* pValue) : pData(pValue)
    {
    }
    ~SP()
    {
        delete pData;
    }

    T& operator* ()
    {
        return *pData;
    }

    T* operator-> ()
    {
        return pData;
    }
};
Run Code Online (Sandbox Code Playgroud)

当重载引用运算符时,为什么类型为T&?类似地,当重载结构解除引用时为什么是类型T*?

Mat*_*att 50

dereference运算符(*)重载与任何其他运算符重载一样.如果您希望能够修改取消引用的值,则需要返回非const引用.这种方式*sp = value实际上会修改指向的值,sp.pData而不是编译器生成的临时值.

结构解引用operator(->)重载是运算符重载的特例.实际上,在循环中调用运算符,直到返回实际指针,然后取消引用该实际指针.我想这只是他们想到实现它的唯一方法,结果有点像黑客.但它有一些有趣的属性.假设您有以下类:

struct A {
    int foo, bar;
};

struct B {
    A a;
    A *operator->() { return &a; }
};

struct C {
    B b;
    B operator->() { return b; }
};

struct D {
    C c;
    C operator->() { return c; }
};
Run Code Online (Sandbox Code Playgroud)

如果你有一个d类型的对象D,则调用d->bar首先调用D::operator->(),然后C::operator->(),然后B::operator->(),最后返回一个指向struct的实际指针A,并bar以正常方式取消引用其成员.请注意,在以下内容中:

struct E1 {
    int foo, bar;
    E1 operator->() { return *this; }
};
Run Code Online (Sandbox Code Playgroud)

调用e->barwhere e类型E1会产生无限循环.如果你想实际取消引用e.bar,你需要这样做:

struct E2 {
    int foo, bar;
    E2 *operator->() { return this; }
};
Run Code Online (Sandbox Code Playgroud)

总结一下:

  1. 当重载dereference运算符时,类型应该是T&因为这是修改指向的值所必需的pData.
  2. 当重载结构取消引用时,类型应该是T*因为这个操作符是一个特例,它就是它的工作原理.


小智 13

解引用运算符的目的是取消引用指针并返回对象引用.因此它必须返回参考.这就是为什么它是T&.

引用运算符( - >)的目的是返回一个指针,因此返回T*.

  • 我认为这个问题源于"操作符的目的 - >返回指针"的想法是违反直觉的.令人困惑的是:"(*x)." 并且"x->"最终都取消引用x并访问解除引用指针的成员.因此,一个运算符"意味着"返回一个指针而另一个运算符的引用并不是很明显. (4认同)