C++ 重载解引用运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21569483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:42:10  来源:igfitidea点击:

C++ overloading dereference operators

c++

提问by user3273777

I'm relatively new to C++, still trying to get a hang of the syntax. I've been taking a look at a few operator overloading examples, most recently smart pointer implementations. Here's a really generic example I'm looking at:

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

When overloading the dereference operator why is the type T&? Similarly, when overloading the structure dereference why is the type T*?

重载解引用运算符时,为什么类型是 T&?同样,在重载结构解引用时,为什么类型是 T*?

回答by Matt

The dereference operator (*) overload works like any other operator overload. If you want to be able to modify the dereferenced value, you need to return a non-const reference. This way *sp = valuewill actually modify the value pointed to by sp.pDataand not a temporary value generated by the compiler.

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

The structure dereference operator (->) overload is a special case of operator overloading. The operator is actually invoked in a loop until a real pointer is returned, and then that real pointer is dereferenced. I guess this was just the only way they could think of to implement it and it turned out a bit hackish. It has some interesting properties, though. Suppose you had the following classes:

结构体解引用运算符 ( ->) 重载是运算符重载的特例。该运算符实际上在循环中被调用,直到返回一个真正的指针,然后该真正的指针被取消引用。我想这只是他们能想到的实现它的唯一方法,但结果却有点骇人听闻。不过,它有一些有趣的特性。假设你有以下类:

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

If you had an object dof type D, calling d->barwould first call D::operator->(), then C::operator->(), and then B::operator->(), which finally returns a real pointer to struct A, and its barmember is dereferenced in the normal manner. Note that in the following:

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

struct E1 {
    int foo, bar;
    E1 operator->() { return *this; }
};

Calling e->bar, where eis of type E1, produces an infinite loop. If you wanted to actually dereference e.bar, you would need to do this:

调用e->bar,其中e类型为E1,会产生无限循环。如果你想真正取消引用e.bar,你需要这样做:

struct E2 {
    int foo, bar;
    E2 *operator->() { return this; }
};


To summarize:

总结一下:

  1. When overloading the dereference operator, the type should be T&because that is necessary to modify the value pointed to by pData.
  2. When overloading the structure dereference, the type should be T*because this operator is a special case and that is just how it works.
  1. 重载解引用运算符时,类型应该是,T&因为这是修改 指向的值所必需的pData
  2. 当重载结构解引用时,类型应该是T*因为这个运算符是一个特殊情况,这就是它的工作原理。

回答by Saminathan S

The purpose of dereference operator is to dereference a pointer and returns the object reference. Hence it must return the reference. That is why it is T&.

解引用运算符的目的是解引用一个指针并返回对象引用。因此它必须返回引用。这就是为什么它是 T&。

The purpose of referring operator (->) is to return a pointer and hence T* is returned.

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

回答by luck

It is because pointer contains an address of a variable referencing it will give a reference (or to say a lvalue refrence) to the address it has stored. e.g. int x; int *p; p=&x;now xand *pcan be used interchangeably. if you do x =4;or *p = 4;both will have same result. *pworks as a reference to xjust like a normal reference int& t = x;will work.

这是因为指针包含引用它的变量的地址,它将提供对它存储的地址的引用(或说左值引用)。例如int x; int *p; p=&x;现在x*p可以互换使用。如果你这样做x =4;*p = 4;两者都会有相同的结果。就像正常参考一样*p工作作为参考。xint& t = x;

Next thing structure dereference operator. This operator gives you the access of member variables through a pointer to object of a class. In above example the member is T* pData;so using this operator will give access to pDataand pDatais T*so the return type is T*. if pDatain above example would have been Tthen the return type would have been T.

Next thing 结构解引用运算符。该运算符使您可以通过指向类对象的指针访问成员变量。在上面的例子中部件T* pData;,因此使用此操作者就可以访问pDatapDataT*那么返回类型为T*。如果pData在上面的例子中是,T那么返回类型应该是T.

回答by darune

Overloaded operators are just functions

重载运算符只是函数

When overloading operaters you are free to return anything basicly (just like any other function), with the noteable exception of member of pointer->being somewhat special in this way.

当重载操作符时,您基本上可以自由地返回任何内容(就像任何其他函数一样),但指针成员的显着例外->在这种方式中有些特殊。

In the example you show, a smart pointer, you aim to mimick the syntax of a pointer (pointer semantic). Then for syntax like:

在您展示的示例中,智能指针旨在模仿指针的语法(指针语义)。然后对于像这样的语法:

*p = 2;

The indirection operator*return a non-const referenceto object and we are able to modify through operator*. In effect, usually used for proxytype classes in the same way and it is a sort of a convention - but you could in theory return whatever.

间接operator*返回一个对 object的非常量引用,我们可以通过operator*. 实际上,通常以相同的方式用于代理类型类,这是一种约定 - 但理论上您可以返回任何内容。

The member of pointeroperator ->is a bit tricky. See this answerfor an explanation.

指针运算符的成员->有点棘手。请参阅此答案以获取解释。

回答by Pankaj

We are making smart pointer and our aim is to access member of class/structure using any of this T& (reference) or T* (pointer) with flexibility.

我们正在制作智能指针,我们的目标是使用任何 T&(引用)或 T*(指针)灵活地访问类/结构的成员。

for T* operator-> ():

对于 T* 运算符-> ():

T* operator-> ()
{
  return pData;
}
arrow operator (->) is a shorthand for (*p) and hence we return *pData which is of   type T*. 
here we are Overloding arrow operator so that members of T can be accessed like a pointer.

for T& operator* ():

对于 T& 运算符* ():

T& operator* ()
{
  return *pData;
}
    * is "value at address" operator, here we are Overloding * (pointer) operator so 
    that members can be accessed  through a reference (T&).

We can change the behavior of the operator with operator overloading but its not recommended. overloaded operator behavior should be as close as its basic functionality.

我们可以通过运算符重载来改变运算符的行为,但不推荐这样做。重载操作符的行为应该与其基本功能一样接近。