c++ - 模板派生类中的错误 "Pure virtual function called"

标签 c++ templates inheritance pure-virtual

我需要做一个通用 Robot这将在一般 Surface 上找到路径.

这是我的 Surface界面:

template <typename P>
class Surface {
public:
    virtual int distance(const P& from, const P& to) const = 0;
    virtual bool check(const vector<P>& path, const P& from, const P& to) const = 0;
    virtual vector<P> lookAround(const P& at) const = 0;
};

我在这里创建了一个简单的 PlanarSurface :

class PlanarSurface : public Surface<pair<int, int>> {
public:
    using point_type = pair<int, int>;
    int distance(const point_type& from, const point_type& to) const override {
        return to.first - from.first + to.second - from.second;
    }

    bool check(const vector<point_type>& path, 
               const point_type& from, 
               const point_type& to) const override {
        return true; // there would be the check
    }

    vector<point_type> lookAround(const point_type& at) const override {
        vector<point_type> result;
        //...
        return result;
    }
};

现在我创建一个抽象类 Robot这样每个用户实现的机器人都会扩展它:

template <typename P>
class Robot {
public:
    Robot(const Surface<P>& s): surface(s) {}
    vector<P> findPath(const P& from, const P& to) {
        auto path = searchPath(from, to);
        if (surface.check(path, from, to)) {
            return path;
        }
        throw runtime_error("path not found or incorrect");
    }
private:
    virtual vector<P> searchPath(const P& from, const P& to) = 0;
protected:
    const Surface<P>& surface;
};

searchPath私有(private)方法将负责自定义搜索算法,在 Robot 的子项中定义. 假设我有一个:

template <typename P>
class MyRobot: public Robot<P> {
public:
    MyRobot(Surface<P> m): Robot<P>(m) {}
private:
    vector<P> searchPath(const P& from, const P& to) override {
        vector<P> result;
        // ...
        // use one of surface's virtual methods
        auto dist = this->surface.distance(from, to); // Pure virtual function called!
        cout << dist << endl;
        // ...
        return result;
    }
};

最后是 main功能:

int main(const int argc, const char **argv) {
    PlanarSurface plane;
    MyRobot<pair<int, int>> robot(plane);
    robot.findPath({1,2}, {3,4});
    return 0;
}

所以问题是作为对 surface 的引用存储在基地 Robot我们无法用 Surface 的一些派生类指定它的类型类(class)。所以引用的类型只能是Surface<P, M> .

我们需要使用 surfacedistancelookAround Robot 的每个 child 的搜索算法中的方法.但是在Surface<P, M>它们是纯虚拟的。而且它们只能在 Surface<P, M> 的 child 中实现.

请帮帮我!也许我错过了一些明显的东西..

最佳答案

错误在这里:

MyRobot(Surface<P> m) : Robot<P>(m) {}
        ^^^^^^^^^^^^ value

改为接受引用

MyRobot(Surface<P>& m) : Robot<P>(m) {}

有趣的是,MSVC 和 gcc 都按照以下方式诊断此问题

invalid abstract parameter

虽然 clang 甚至没有对此发出警告(在撰写本文时 - 4.0)

关于c++ - 模板派生类中的错误 "Pure virtual function called",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40864104/

相关文章:

c++ - 使用 ctime 将给定日期提前到下一个日历日期的问题

c++ - 为两个类之间具有循环依赖关系定义重载转换运算符

javascript - JavaScript 模板引擎的现状?

delphi - 为什么我的类实现子接口(interface),而不实现其父接口(interface)?

java - 如何更改子类中变量的实现?

c++ - 在 OSX 上安装 SDL

c++ - 在 set 方法中赋值前检查当前值

c++ - 可调用对象作为默认模板参数

php - Drupal 主题不会读取 CSS 文件

c# - 为什么当存在不明确的虚拟方法时此 C# 代码编译正常?