简体   繁体   English

为什么重载运算符 - >()有用?

[英]Why is overloading operator->() useful?

I saw the following example in book of the C++ Programming Language 我在C ++编程语言一书中看到了以下示例

class Ptr {
     X* operator->( );
};

 voide f(Ptr p)
 {
   p->m=7;
   X* q1 = p->;
   X* q2 = p.operator->();
 }

The book claims that 1)Objects of class Ptr can be used to access members of class X in a very similar manner to the way pointers are used. 该书声称1)类Ptr的对象可以用于以与指针使用方式非常类似的方式访问类X的成员。 2)The transformation of the object p into the pointer p.operator->() does not depend on the member m pointed to. 2)将对象p转换为指针p.operator - >()不依赖于指向的成员m。 That is the sense in which operator->( ) is a unary postfix operator. 这就是operator - >()是一元后缀运算符的意义。

For the first point, I do not understand why we need to this design, or in which scenarios should use this kind of design. 对于第一点,我不明白为什么我们需要这种设计,或者在哪种情况下应该使用这种设计。 For the second point, I am confused about the message that the author want to deliver. 对于第二点,我对作者想要提供的信息感到困惑。

Thanks. 谢谢。

This operator is overloaded when implementing objects that behave like (pretend to be) pointers. 在实现行为类似(伪装成)指针的对象时,此运算符会过载。

A good example would be boost::shared_ptr , which is a classic reference counting pointer that automatically deletes the pointed-to object when all pointers are destroyed. 一个很好的例子是boost::shared_ptr ,它是一个经典的引用计数指针,当所有指针都被销毁时它会自动删除指向的对象。 Countless other similar "smart pointer" objects have been implemented by people for all sorts of reasons. 由于种种原因,人们已经实施了无数其他类似的“智能指针”对象。

(and, as pointed out the stl iterators also use this to behave like pointers, allowing syntax like it->method(); or it->data; ) (并且,正如所指出的那样,stl迭代器也使用它来表现像指针一样,允许语法如it->method();或者it->data;

  1. This design is extremely useful when we want to create a class that behaves like a pointer; 当我们想要创建一个行为类似于指针的类时,这种设计非常有用; this is the case of smart pointers (objects that have a pointer-like interface but that provide additional "services", eg automatic deallocation on destruction, ownership transfer, reference counting, ...). 这是智能指针的情况(具有指针式界面但提供额外“服务”的对象,例如销毁时的自动解除分配,所有权转移,引用计数......)。

    Notice that often this kind of object will also overload the * (dereference) operator to mimic pointers more closely. 请注意,通常这种对象也会重载* (取消引用)运算符以更接近地模仿指针。

  2. The author wants to say that when you use the -> operator on Ptr , it's not relevant (as far as operator-> is concerned) what you put after it: in any case, the operator-> method will be called, that will return a pointer to the object that will be considered for the rest of the expression. 作者想说的是,当你在Ptr上使用->运算符时,它与你之后的内容无关(就operator->而言):无论如何,将调用operator->方法,返回指向将考虑表达式其余部分的对象的指针。


To make this more clear: quoting directly from the standard: 为了更清楚:直接引用标准:

13.5.6 Class member access 13.5.6类成员访问

operator-> shall be a non-static member function taking no parameters. operator->应该是一个不带参数的非静态成员函数。 It implements class member access using -> 它使用->实现类成员访问

 postfix-expression -> id-expression 

An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T::operator->() exists and if the operator is selected as the best match function by the overload resolution mechanism (13.3). 如果存在T::operator->()并且如果选择运算符作为最佳匹配函数,则表达式x->m被解释为(x.operator->())->m用于类型为T的类对象x通过重载解析机制(13.3)。

In other words: 换一种说法:

  • if you call operator->() directly (second and third example in the OP code), you will get the pointer returned by the operator-> method, just like what happens with any method; 如果你直接调用operator->() (OP代码中的第二个和第三个例子),你将获得operator->方法返回的指针,就像任何方法一样;
  • if you put stuff after the -> operator (eg x->m , as in the first example in the OP code), the overloaded operator-> will be called, and the returned pointer will be used as if the ->m was being used over it. 如果你把东西放在->运算符之后(例如x->m ,就像在OP代码的第一个例子中那样),将调用重载的operator-> ,并且返回的指针将被用作->m是被用在它上面。

iterators ... a fundamental part of the C++ standard library . 迭代器 ...... C++ standard library的基本部分。

std::list<std::string> list_of_string
std::list<std::string>::iterator i;
for(i = list_of_string.begin(); i != list_of_string.end(); ++i)
{
  //WHERE -> IS OVERLOADED...
  printf("%s\n", i->c_str()); //print to the screen, printf() is C and requires a C-string.
}

normally, i should be thought of as a std::list<> object, not a std::string . 通常, i应该将其视为std::list<>对象,而不是std::string Normally c_str() would be inaccessible too, without the -> overloaded. 通常c_str()也是不可访问的,没有 - >重载。

it allows for creating smart pointers. 它允许创建智能指针。 (little objects that behave just like normal pointers) (与正常指针一样的小物体)

The main reason for this is automatic memory management. 主要原因是自动内存管理。 But can also be used for things like proxys 但也可以用于代理之类的东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM