Apparently you can =delete
virtual functions:
struct A
{
virtual void foo() = delete;
};
struct B : A
{
void foo() override = delete;
};
Interestingly, both functions have to be =delete
d, or both not. You get a compilation error otherwise.
What is the point of this feature? It seems some thought went into this (since inconsistent deletion is banned, see above), so it looks like this was allowed intentionally?
It appears to be an ABI compatibility tool, to add dummy entries to the vtable.
Despite being impossible to call in legal C++, those functions still get entries in the vtable that crash the program when executed, like pure virtual functions (as specified in the Itanium ABI, and can also be confirmed experimentally on MSVC ABI).
You can confirm this with the following example: (which technically violates ODR)
struct A
{
virtual void a() {std::cout << "a\n";}
// If you comment this out, calling `c()` in the other file crashes.
virtual void b() = delete;
virtual void c() {std::cout << "c\n";}
};
void foo(A &);
int main()
{
A a;
foo(a);
}
struct A
{
virtual void a() = 0;
virtual void b() = 0;
virtual void c() = 0;
};
void foo(A &a)
{
a.a();
// a.b(); // Crashes.
a.c(); // Crashes if you comment out the deleted `b()` in the other file.
}
While you can use this to disable some overloads, this wastes space in the vtable, so it doesn't feel like a good idea (despite the cost being minimal).
Especially given that making deleted functions non-virtual works equally well, except for one exception shown in @Caleth's answer, which is that derived classes can shadow deleted non-virtual functions with non-deleted functions, but can't do this with deleted virtual functions.