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

发布于 2024-10-20 12:39:21 字数 394 浏览 3 评论 0原文

我在《C++ 编程语言》一书中看到了以下示例,

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

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

该书声称 1) 类 Ptr 的对象可用于访问类 X 的成员,其方式与使用指针的方式非常相似。 2)对象p到指针p.operator->()的转换不依赖于m指向的成员。这就是operator->( ) 是一元后缀运算符的意义。

对于第一点,我不明白为什么需要这样的设计,或者在什么场景下应该使用这样的设计。 对于第二点,我对作者想要传达的信息感到困惑。

谢谢。

I saw the following example in book of the C++ Programming Language

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.
2)The transformation of the object p into the pointer p.operator->() does not depend on the member m pointed to. That is the sense in which operator->( ) is a unary postfix 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烂人 2024-10-27 12:39:21

当实现行为类似于(假装是)指针的对象时,此运算符会重载。

一个很好的例子是 boost::shared_ptr,这是一个经典的引用计数指针,当所有指针被销毁时,它会自动删除所指向的对象。由于各种原因,人们已经实现了无数其他类似的“智能指针”对象。

(并且,正如所指出的,stl 迭代器也使用它来表现得像指针,允许像 it->method();it->data; 这样的语法)

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. 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;)

待"谢繁草 2024-10-27 12:39:21
  1. 当我们想要创建一个行为类似于指针的类时,这种设计非常有用;这是智能指针(具有类似指针的接口但提供附加功能的对象)的情况“服务”,例如销毁时自动重新分配、所有权转移、引用计数……)。

    请注意,这种对象通常还会重载 *(取消引用)运算符以更接近地模仿指针。

  2. 作者想说的是,当您在 Ptr 上使用 -> 运算符时,它是不相关的(就 operator-> 而言) code> 涉及)您在其后面放置的内容:在任何情况下,都会调用 operator-> 方法,该方法将返回一个指向对象的指针,该对象将被考虑用于表达式的其余部分.


为了更清楚地说明这一点:直接引用标准:

13.5.6 班级成员访问

operator-> 应是不带参数的非静态成员函数。它使用 ->

实现类成员访问

后缀表达式 -> id-表达式

对于类对象 x<,表达式 x->m 被解释为 (x.operator->())->m如果 T::operator->() 存在并且重载解析机制将运算符选为最佳匹配函数 (13.3),则为 T 类型的 /code> .


换句话说:

  • 如果直接调用operator->()(操作代码中的第二个和第三个示例),您将获得operator->返回的指针> 方法,就像任何方法所发生的情况一样;
  • 如果您在 -> 运算符之后添加内容(例如 x->m,如 OP 代码中的第一个示例),则重载的 operator- > 将被调用,并且将使用返回的指针,就像在其上使用 ->m 一样。
  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", e.g. 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.


To make this more clear: quoting directly from the standard:

13.5.6 Class member access

operator-> shall be a non-static member function taking no parameters. 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).

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;
  • if you put stuff after the -> operator (e.g. 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.
累赘 2024-10-27 12:39:21

迭代器...C++ 标准库的基本组成部分。

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

通常,i 应被视为 std::list 对象,而不是 std::string。通常 c_str() 也将无法访问,如果没有 ->;超载。

iterators... a fundamental part of the 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. Normally c_str() would be inaccessible too, without the -> overloaded.

独守阴晴ぅ圆缺 2024-10-27 12:39:21

它允许创建智能指针。 (行为就像普通指针一样的小对象)

主要原因是自动内存管理。但也可以用于代理之类的东西

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文