user3131721
user3131721

Reputation: 23

How to implement pure virtual function

Consider following example

#include <iostream>

struct PureVirtual {
    virtual void Function() = 0;
};

struct FunctionImpl {
    virtual void Function() {
        std::cout << "FunctionImpl::Function()" << std::endl;
    }   
};

struct NonPureVirtual : public FunctionImpl, public PureVirtual {
    using FunctionImpl::Function;
};

int main() {
    NonPureVirtual c;
    c.Function();
}

Compiler (GCC 4.9, Clang 3.5) is exits with error

test.cpp:18:20: error: variable type 'NonPureVirtual' is an abstract class
    NonPureVirtual c;
                   ^
test.cpp:4:18: note: unimplemented pure virtual method 'Function' in 'NonPureVirtual'
    virtual void Function() = 0;
             ^

But when I don't derive form Pure Virtual everything is OK. This is weird because Standard 10.4.4 says

A class is abstract if it contains or inherits at least one pure virtual function for which the final overrider is pure virtual.

They are not saying anything about what the final overrider is but I suppose it should be FunctionImpl::Function() especially when I made it available through using directive. So why is still Non Pure Virtual abstract class and how can I fix this ?

Upvotes: 2

Views: 1808

Answers (3)

Tobias
Tobias

Reputation: 5198

The following source code demonstrates my comment about virtual inheritance with an example. It compiles and runs fine.

#include <iostream>

struct PureVirtual {
    virtual void Function() = 0;
};

struct FunctionImpl : public virtual PureVirtual {
    virtual void Function() {
        std::cout << "FunctionImpl::Function()" << std::endl;
    }   
};

struct NonPureVirtual : public FunctionImpl, public virtual PureVirtual {
    using FunctionImpl::Function;
};

int main() {
    NonPureVirtual c;
    c.Function();
}


/*
Local Variables:
compile-command: "g++ ./test.cc"
End:
 */

Upvotes: 1

AndersK
AndersK

Reputation: 36082

When you derive from a pure virtual class you need to override all pure virtual functions if you want to create an instance of the class. The FunctionImpl is completely unrelated to PureVirtual

So

struct NonPureVirtual : public FunctionImpl, public PureVirtual {
    using FunctionImpl::Function;
};

is not enough, you need to implement void Function in the class NonPureVirtual

struct NonPureVirtual : public FunctionImpl, public PureVirtual {
    void Function() {}
};

Upvotes: 0

Diboliya
Diboliya

Reputation: 1174

FunctionImpl::Function and PureVirtual::Function are different functions from different classes.

Their respective types are void (FunctionImpl::*)() and void (PureVirtual::*)(). Since PureVirtual and FunctionImpl are unrelated classes, these function types are unrelated.

They happen to have the same name and the same parameters and return type, but since they're different, the using FunctionImpl::Function line doesn't make that function an override of the one in PureVirtual.

And if you declared a variable of type void (PureVirtual::*)(), you wouldn't be able to assign FunctionImpl::Function to it.

In other words, the final override of PureVirtual::Function is the original one in PureVirtual, which is pure virtual.

Upvotes: 1

Related Questions