Deleting virtual functions in C++0x
-
29-09-2019 - |
Question
It isn't clear what happens if I delete a virtual method in C++0x:
virtual int derive_func() = delete;
Does this mean this class and everything that inherits from it can not define/implement the derive_func()
method? Or is this illegal/compile error?
Solution
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html#delete
A deleted virtual function may not override a non-deleted virtual function and vice-versa.
meaning its pretty useless (as i read it at least) the only valid use would be:
struct A{
virtual void b() = delete;
};
struct B:A{
virtual void b() = delete;
};
which is completely useless, since the function can never be called. for non virtual functions the use is more justified
EDIT to be completely clear this is the ONLY possible relation, children may not implement and you may not delete a non-deleted inherited virtual.
OTHER TIPS
flownt got it right, but I want to point out that in the final C++11 draft (N3337), the corresponding language has moved to section 10.3#16:
A function with a deleted definition shall not override a function that does not have a deleted definition. Likewise, a function that does not have a deleted definition shall not override a function with a deleted definition.2
It seems fairly clear to me (section 8.4.3#1) that a deleted definition does in fact count as a definition, and in fact an inline definition, which means a deleted definition satisfies 10.3#11:
A virtual function declared in a class shall be defined, or declared pure in that class, or both; but no diagnostic is required.2
However, it seems that current implementations disagree. Here's my test case:
struct Base {
virtual void bar();
virtual void foo() = delete;
};
void Base::bar() { } // a definition of the first non-inline virtual function
int main() { Base b; }
Clang produces an unlinkable program:
Base::foo
is mentioned in the vtable forBase
. And if you swap the order offoo
andbar
, the linker complains that the entire vtable is missing (because Clang thinksfoo
is a non-inline function with no definition). I filed this as a bug; we'll see what the developers think.GCC complains about a "use" of
foo
at the end of the translation unit, when it creates the vtable; but it does correctly identifybar
as the first non-inline virtual member function, no matter the order offoo
andbar
.