Class isn't abstract but I get Error C2259: cannot instantiate abstract class

I'm trying to implement a Strategy pattern in C++, but I get the following error:

Error 1 error C2259: 'LinearRootSolver' : cannot instantiate abstract class

Here's my code (the line where the error is, is marked with a comment). Class that uses strategy pattern (context):

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

And here's my strategy pattern classes:

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) {
        [...]
    }
};

I can't see why I get an error for trying to instantiate an abstract class in the intersect method at the top?

Upvotes: 6

Views: 19660

Answers (3)

taocp
taocp

Reputation: 23624

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

and

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

parameter type mismatch, so findRoot inherited form based class is still a pure virtual function (not overriding), which make the LinearRootSolver class an abstract class. When you do:

  INumericalRootSolver *rootSolver = new LinearRootSolver();

it tries to create an object of abstract class, you got the compiler error.

Upvotes: 7

confusopoly
confusopoly

Reputation: 1245

Your derived class uses references and your interface uses pointers.

You need to have the same method signature for both methods in order to get a proper override.

Upvotes: 2

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

Your definition for LinearRootSolver::findRoot has the wrong signature. In particular, the first argument should be a pointer according to the declaration in INumericalRootSolver:

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

In C++11, you can avoid this mistake by using the override keyword:

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

This wouldn't compile because the function doesn't override a function from the base class.

Upvotes: 2

Related Questions