【问题标题】:Calling a function on a pointer from a std::list<Shape*>::iterator从 std::list<Shape*>::iterator 调用指针上的函数
【发布时间】:2016-07-19 01:55:44
【问题描述】:

我有一个基本的 C++ 多态示例,结构如下。

struct Shape {
    virtual void draw() = 0;
};

struct Circle : public Shape {
    virtual void draw() {
        cout << "drawing circle" << endl;
    }
};

struct Triangle : public Shape {
    virtual void draw() {
        cout << "drawing triangle" << endl;
    }
};

我有一个使用此设置的函数来调用绘图函数:

void drawShapes(list<Shape*> shapes) {
    list<Shape*>::iterator pShape = shapes.begin();
    list<Shape*>::iterator pEnd = shapes.end();

    for (; pShape != pEnd; pShape++) {
        pShape->draw();
    }
}

这正是我正在阅读的书中示例的设置方式。尝试编译时出现以下错误。

expression must have a pointer-to-class type

我通过将pShape-&gt;draw(); 更改为(*pShape)-&gt;draw() 来解决此问题。

然后我将此作为可能的错误提交给本书的作者,他对此做出了回应

“实际上并非如此,因为 std::list::iterator 有一个 operator->() 函数,它将迭代器解析为 T*(在本例中为 Shape*)。”

我仍然无法编译原始版本。我正在使用与 VS2015 捆绑在一起的编译器来进行这些测试。有谁知道我为什么会收到这个错误?

【问题讨论】:

  • 糟糕的反应。请问是什么书?
  • 当然,每个人都会犯错。但他至少应该在回应之前尝试一下。
  • 由于 pShape 是一个迭代器,取消引用迭代器会生成原始 T 值,在这种情况下:Shape*,然后必须取消引用。

标签: c++ c++11 iterator stdlist


【解决方案1】:

你是对的,作者是错的。 std::list&lt;T&gt;::iterator::operator* 返回 T*,这是真的。但在这种情况下,TShape*,这使得T* == Shape**。您需要取消引用一次才能获得Shape*。这就是为什么pShape-&gt;draw() 失败,但(*pShape)-&gt;draw() 有效。

【讨论】:

    【解决方案2】:
    pShape->draw();
    

    应该是

    (*pShape)->draw();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多