【问题标题】:recursive application of operator->operator->的递归应用
【发布时间】:2012-05-14 16:43:04
【问题描述】:

据说箭头运算符是递归应用的。但是当我尝试执行以下代码时,它应该打印 4 时会打印乱码。

class dummy
{
public:
    int *p;

    int operator->()
    {
        return 4;
    }
};

class screen 
{
public:
    dummy *p;

    screen(dummy *pp): p(pp){}
    dummy* operator->()
    {
        return p;
    }
};

int main()
{
    dummy *d = new dummy;
    screen s(d);
    cout<<s->p;
    delete d;
}

【问题讨论】:

  • 哪里说是“递归应用”?
  • 不,我不同意您的示例按预期工作, -> 操作符本质上只是一个函数调用,为什么要深入研究?如果这样做,您将如何控制在什么级别停止取消引用,这将使继承和多态性比现在更加复杂
  • C++ Primer,第四版,作者 Stanley B. Lippman,第 14.6 节最后一段。

标签: c++


【解决方案1】:

Stanley 所说的“递归”的意思只是将运算符应用于每个返回的对象直到返回的类型是一个指针。

第一次尝试时会发生这种情况:screen::operator -&gt; 返回一个指针。因此,这是编译器尝试的对operator -&gt; 的最后一次调用。然后,它通过在返回的指针类型 (dummy) 中查找具有该名称的成员来解析运算符 (p) 的右手边。

基本上,只要编译器在代码中找到语法aᵢ-&gt;b,它就会应用以下算法:

  1. aᵢ 是指针类型吗?如果是这样,请解析*aᵢ 的成员b 并调用(*aᵢ).b
  2. 否则,尝试解析aᵢ::operator -&gt;
    1. 成功时,设置aᵢ₊₁ = aᵢ::operator -&gt;()。转到 1。
    2. 失败时,发出编译错误。

我很难想出一个简短而有意义的例子,其中operator -&gt; 调用的 甚至是有意义的。可能唯一真正的用途是在编写智能指针类时。

但是,以下玩具示例至少编译并生成了一个数字。但我不建议实际编写这样的代码。它会破坏封装并让小猫哭泣。

#include <iostream>

struct size {
    int width;
    int height;
    size() : width(640), height(480) { }
};

struct metrics {
    size s;
    size const* operator ->() const {
        return &s;
    }
};

struct screen {
    metrics m;
    metrics operator ->() const {
        return m;
    }
};

int main() {
    screen s;
    std::cout << s->width << "\n";
}

【讨论】:

  • 如果你能告诉我如何在这个例子中打印出 4,我的概念可能会更清楚..
  • @user1232138 你不能。 operator -&gt; 链中的最后一个调用必须返回一个指针。
  • @user1232138 但是,请参阅我的更新以获取工作示例。请注意,我之前所说的仍然有效。你必须返回一个指针——所以如果你想检索一个整数值,它需要存储在运算符的右侧表达式中(在本例中为size::width)。
  • operator-&gt;* 是否遵守相同的规则?
  • @AlexandreC。我不知道。我不知道operator -&gt;* 实际是如何工作的——例如,Catch.hpp 使用它来获取后续表达式的字符串表示。就我而言,他妈的魔法。
【解决方案2】:

C++ Primer(第 5 版)在第 570 页将其表述如下:

箭头运算符永远不会失去其成员访问的基本含义。当我们重载箭头时,我们改变了箭头从中获取指定成员的对象。我们无法改变箭头获取成员的事实。

【讨论】:

    【解决方案3】:

    一旦screen::operator-&gt;() 返回一个指针 (dummy*),递归就会停止,因为该指针上使用了内置(默认)-&gt;。如果你想要递归,你应该从screen::operator-&gt;()返回dummydummy&amp;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-20
      • 2019-03-23
      • 2014-04-07
      • 1970-01-01
      • 2019-10-18
      • 2011-09-16
      • 2013-11-15
      • 1970-01-01
      相关资源
      最近更新 更多