4

我正在尝试在 C++ 中实现策略模式,但出现以下错误:

错误 1 ​​错误 C2259:“LinearRootSolver”:无法实例化抽象类

这是我的代码(错误所在的行标有注释)。使用策略模式(上下文)的类:

bool Isosurface::intersect(HitInfo& result, const Ray& ray, float tMin, float tMax) {
    INumericalRootSolver *rootSolver = new LinearRootSolver(); // error here
    [...]
}

这是我的策略模式类:

class INumericalRootSolver {
public:
    virtual void findRoot(Vector3* P, float a, float b, Ray& ray) = 0;
};

class LinearRootSolver : public INumericalRootSolver {
public:
    void findRoot(Vector3& P, float a, float b, Ray& ray) {
        [...]
    }
};

我不明白为什么尝试在顶部的 intersect 方法中实例化抽象类时出错?

4

3 回答 3

6
 void findRoot(Vector3* P, float a, float b, Ray& ray) = 0;
                    //^^

void findRoot(Vector3& P, float a, float b, Ray& ray) 
              //^^

参数类型不匹配,所以findRoot继承形式的类仍然是一个纯虚函数(不是覆盖),这使得LinearRootSolver类成为一个抽象类。当你这样做时:

  INumericalRootSolver *rootSolver = new LinearRootSolver();

它试图创建一个抽象类的对象,你得到了编译器错误。

于 2013-05-18T19:10:48.380 回答
2

您的定义LinearRootSolver::findRoot签名错误。特别是,第一个参数应该是根据以下声明的指针INumericalRootSolver

void findRoot(Vector3* P, float a, float b, Ray& ray) {
//                   ^ Here
    [...]
}

在 C++11 中,可以通过使用override关键字来避免这个错误:

void findRoot(Vector3& P, float a, float b, Ray& ray) override {
    [...]
}

这不会编译,因为该函数不会覆盖基类中的函数。

于 2013-05-18T19:09:34.630 回答
1

您的派生类使用引用,而您的接口使用指针。

您需要对这两种方法具有相同的方法签名才能获得正确的覆盖。

于 2013-05-18T19:10:06.023 回答