【问题标题】:Class isn't abstract but I get Error C2259: cannot instantiate abstract class类不是抽象类,但出现错误 C2259:无法实例化抽象类
【发布时间】:2013-05-13 17:45:01
【问题描述】:

我正在尝试在 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 方法中实例化抽象类时出错?

【问题讨论】:

    标签: c++ visual-c++ compiler-errors


    【解决方案1】:
     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();
    

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

    【讨论】:

    • 天哪。这是一个邪恶的错字,感谢您为我找到它。呵呵。
    【解决方案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 {
        [...]
    }
    

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-25
        • 2012-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-07
        相关资源
        最近更新 更多