[英]C++ overloading dereference operators
I'm relatively new to C++, still trying to get a hang of the syntax.我对 C++ 比较陌生,仍在尝试掌握语法。 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:这是我正在查看的一个非常通用的示例:
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&?重载解引用运算符时,为什么类型是 T&? Similarly, when overloading the structure dereference why is the type T*?同样,在重载结构解引用时,为什么类型是 T*?
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 = value
will actually modify the value pointed to by sp.pData
and 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 d
of type D
, calling d->bar
would first call D::operator->()
, then C::operator->()
, and then B::operator->()
, which finally returns a real pointer to struct A
, and its bar
member is dereferenced in the normal manner.如果你有一个D
类型的对象d
,调用d->bar
将首先调用D::operator->()
,然后是C::operator->()
,然后是B::operator->()
,最后返回一个指向 struct A
的实指针,并且它的bar
成员以正常方式取消引用。 Note that in the following:请注意,在以下内容中:
struct E1 {
int foo, bar;
E1 operator->() { return *this; }
};
Calling e->bar
, where e
is of type E1
, produces an infinite loop.调用e->bar
,其中e
是E1
类型,会产生一个无限循环。 If you wanted to actually dereference e.bar
, you would need to do this:如果您想实际取消引用e.bar
,则需要执行以下操作:
struct E2 {
int foo, bar;
E2 *operator->() { return this; }
};
To summarize:总结一下:
T&
because that is necessary to modify the value pointed to by pData
.当重载解引用运算符时,类型应该是T&
因为这是修改pData
指向的值所必需的。T*
because this operator is a special case and that is just how it works.当重载结构解引用时,类型应该是T*
因为这个运算符是一种特殊情况,这就是它的工作原理。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*。
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.这是因为指针包含引用它的变量的地址,它将提供对它存储的地址的引用(或说左值引用)。 eg int x; int *p; p=&x;
例如int x; int *p; p=&x;
int x; int *p; p=&x;
now x
and *p
can be used interchangeably.现在x
和*p
可以互换使用。 if you do x =4;
如果你做x =4;
or *p = 4;
或*p = 4;
both will have same result.两者都会有相同的结果。 *p
works as a reference to x
just like a normal reference int& t = x;
*p
用作对x
的引用,就像普通引用int& t = x;
will work.将工作。
Next thing structure dereference operator. Next thing 结构解引用运算符。 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;
在上面的例子中,成员是T* pData;
so using this operator will give access to pData
and pData
is T*
so the return type is T*
.所以使用这个运算符可以访问pData
并且pData
是T*
所以返回类型是T*
。 if pData
in above example would have been T
then the return type would have been T
.如果上面示例中的pData
是T
则返回类型将是T
。
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 reference to object and we are able to modify through operator*
.间接operator*
返回对对象的非常量引用,我们可以通过operator*
进行修改。 In effect, usually used for proxy type classes in the same way and it is a sort of a convention - but you could in theory return whatever.实际上,通常以相同的方式用于代理类型类,这是一种约定 - 但理论上您可以返回任何内容。
The member of pointer operator ->
is a bit tricky.指针运算符->
的成员有点棘手。 See this answer for an explanation.请参阅此答案以获取解释。
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.重载操作符的行为应该与其基本功能一样接近。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.