Question

I have boiled down my issue to the following code all in a single *.cpp file:

class A {
public:
    A() {};

    int PerformAction() {
        return Action();
    }

protected:
    virtual int Action();
}

class B: public A {
protected:
    int Action();
}

int B::Action() {
   return 4;
}

int main() {
    B newB;
    newB.PerformAction();
};

The previous code throws an Unresolved external symbol error on B::Action(). Changing a::Action()'s definition to:

virtual int Action() = 0;

yields instead the Cannot instantiate abstract class compiler error where it is used in the main function. All of the answers I have seen relate to having the code spread across multiple files, but this is occurring all within one source file. I imagine it is related to B's implementation of Action() being outside the class definition of B but can't see any reason why it should cause any error.

Was it helpful?

Solution

Your error messages, taken together, indicate a signature mismatch between A::Action and B::Action, such that B::Action does not become an overrider. The signatures must match perfectly (including cv-qualification of this), except that return type covariance is allowed.

And B::Action must be virtual. It will be implicitly if the signature matches, unless it is a template. Templates can't override.

If you have a C++11 compiler, I suggest using the override keyword, to make signature mismatch a compile error.

OTHER TIPS

The previous code throws an Unresolved external symbol error on B::Action().

Indeed, all non-pure virtual functions must be defined, so that their address can be stored in the virtual function table for the class.

yields instead the Cannot instantiate abstract class compiler error

No it doesn't: http://ideone.com/IS7PJj

You'd get that error if you tried to directly instantiate A, or a subclass which didn't override the pure virtual function. B does override it, and so is not abstract.

Possibly, your real class B has an incorrect signature for Action, so it doesn't actually override the one declared in A. In C++11, you can add the override specifier to the one in B, to get a more helpful error message in that case.

I imagine it is related to B's implementation of Action() being outside the class definition of B

No, that shouldn't be an issue, as long as there's exactly one definition of the function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top