【问题标题】:confusion about operator overload in C++关于 C++ 中运算符重载的困惑
【发布时间】:2021-12-16 07:09:39
【问题描述】:

我定义了一个类来包装原始指针,因此可以自动删除指针。这是我的代码

#include <iostream>
class Entity
{
private:
    std::string e_name;
public:
    Entity():e_name("unknown"){}
    void whoami() {
        std::cout << e_name;
    }
};
class ScopePointer
{
private:
    Entity *_e;
public:
    ScopePointer(Entity *e) : _e(e) {}
    ~ScopePointer() { delete _e; }
    Entity *operator->() { return _e; }
};

int main(int argc, char *argv[])
{
    ScopePointer p(new Entity());
    p->whoami();
}

它运作良好,但我完全不明白p-&gt;whoami(); 是如何运作的。 我的意思是 ScopePointer 中的 operator -> 重载应该像下面这样工作

p.operator->()->whoami();or p->->whoami();

第一个 -&gt; 应该返回 Entity* 和下一个 -&gt; 调用类方法。 为什么只有一个 -> 可以让它工作?

【问题讨论】:

  • 为什么只有一个 -> 可以让它工作?”我不太明白你的意思。它之所以有效,是因为它设计就是这样运作的。允许重载-&gt; 的全部目的是允许类型模仿某些指针功能。如果它不这样工作,那就没用了。
  • 按照您的建议工作有什么好处?
  • -&gt; 运算符有点“神奇”——只要结果是 -&gt; 运算符,它就会“继续运行”。
  • 旁注:对于ScopePointer,还要考虑重载operator*,或取消引用/间接运算符。或者你可以简单地使用std::unique_ptr&lt;Entity&gt;

标签: c++ class pointers operator-overloading


【解决方案1】:

我希望引用 C++ 14 标准的这段话有助于理解运算符的工作原理。

C++ 14 标准(13.5.6 类成员访问,p #1)

一个表达式 x->m 被解释为一个类的 (x.operator->())->m 如果 T::operator->() 存在并且操作符是 T 类型的对象 x 被重载决议选为最佳匹配函数 机制。

所以重载运算符实际上是内置运算符的“前缀表达式”-> 提供了一个用于内置运算符的指针。

【讨论】:

  • 谢谢,很有帮助
【解决方案2】:

我完全不明白p-&gt;whoami(); 的工作原理

-&gt; 的普通运算符规则有一个例外,即您只需要一个-&gt;。该语言要求实现递归地评估operator-&gt;,直到它找到一个指针对象,而不是某个类类型的对象。

来自[over.ref]

类成员访问运算符函数是一个名为operator-&gt; 的函数,它是一个不带参数的非静态成员函数。对于表单的表达式

后缀表达式->模板optid-表达式

运算符函数通过重载决议([over.match.oper])选择,表达式被解释为

(后缀表达式.operator-&gt;()) -> 模板optid-表达式

【讨论】:

  • 谢谢,很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多