I'm sure we've all seen code that crashes due to a bug that results in a pure virtual function being called. One simple example is like this:
struct Base
{
Base() { method(); }
virtual void method() = 0;
};
struct Derived : Base
{
void method() {};
};
int main()
{
Derived d;
}
In this case, the call to method()
in the Base
constructor is specifically cited as undefined behaviour by section 10.4/6 of the C++ standard, so it's no surprise that we end up crashing. (Both g++ and Clang warn about this, and in fact linking fails with g++ with this example, though Clang succeeds.)
But, just for fun, can anybody come up with a way to invoke a pure virtual function which does not rely on undefined behaviour?
(I suppose you could argue that if such a method exists then there's a defect in the C++ standard, but I'm just curious...)
EDIT: Several answers guys and thank you, but I should have made it clear that I realise it's legal to make a non-virtual call to a pure virtual function (providing a definition exists somewhere). I was more wondering whether there is any clever loophole in the laws which could result in a virtual call, and thus most likely a crash in the common case of having no definition.
For example, perhaps via multiple inheritance one could perform some clever (legal) cast, but end up with the "wrong" (unimplemented) PV method()
being called, that sort of thing. I just thought it was a fun brainteaser :-)
It's perfectly legal to call a pure virtual function non-virtually:
Derived d;
d.Base::method();
Of course, this requires the function to be defined, which isn't the case in your example.
Depends on what you mean with possible. Here's one which compiles successfully, but will most likely result in a linker error:
struct Base
{
virtual void method() = 0;
};
struct Derived : Base
{
void method() { Base::method(); };
};
int main()
{
Derived d;
d.method();
}
Live example
It compiles because nothing prevents a pure virtual function from actually having a body as well. That can be provided in the same translation unit (in a separate definition), or in a different translation unit. That's why it's a linker error and not a compiler one - just that the function has no body here doesn't mean it doesn't have one elsewhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With