Reputation: 23
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
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
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
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