0
class C
{
    public:
    virtual void f() final = 0;
};

Godbolt

To me this looks like a programming mistake. =0 says it has no implementation yet and must be overriden, but final says that nobody can override it. So it will never have an implementation.

Do I miss something? I wonder that I don't get any warning for above code.

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • Is this something you saw in actual code, and are wondering what the real world use case might have been? Or is it something you thought of, and are wondering why the standard doesn't forbid it? – Brian61354270 Jul 27 '23 at 14:02
  • Of note - clang will warn if the class itself is final. – Drew Dormann Jul 27 '23 at 14:04
  • @Brian61354270: I came up with this code while learning about `virtual`, `override` and `final` in C++. – Thomas Weller Jul 27 '23 at 14:06
  • It is legal : see 2) of https://en.cppreference.com/w/cpp/language/final. The C++ core guidelines are a bit more clear on the intent [R.128 virtual/final/override](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c128-virtual-functions-should-specify-exactly-one-of-virtual-override-or-final) – Pepijn Kramer Jul 27 '23 at 14:09
  • There could be some obscure use in template metaprogramming, but I can't think of anything off the top of my head. – Yksisarvinen Jul 27 '23 at 14:19
  • 2
    Minor point: `=0` doesn't say it has no implementation; it says that derived classes must override the function if the derived type will be used to create an object. Pure virtual functions **can** have implementations. That's sometimes handy to provide default behavior; the derived class can call the base version. – Pete Becker Jul 27 '23 at 14:22
  • @PeteBecker: thanks. I modified the question to say "it has no implementation yet and must be overriden" – Thomas Weller Jul 27 '23 at 14:25
  • @PeteBecker: why should a derived class call f() on the base class, if the base class is implemented as =0? I can't make that work: https://godbolt.org/z/cGTq3ncsM – Thomas Weller Jul 27 '23 at 14:31
  • @PeteBecker: Did you mean "That's sometimes handy to provide default behavior; the *base* class can call the *derived* version."? I think there are some GoF design patterns making use of that. – Thomas Weller Jul 27 '23 at 14:35
  • 1
    C++ allows for a lot of things that don't make sense. It just doesn't opt to forbid the nonsensical things, because C++ is not a nanny language. – Eljay Jul 27 '23 at 14:43
  • @ThomasWeller -- no, the derived version can call the base version. For example, a derived class might call the base version so that the base version does whatever is needed in the base subject, and then continue with the processing needed in the derived class. The base version has to have an implementation, which, if I remember correctly, can only be written inline in the class definition. So `struct base { virtual void f() = 0 { std::cout << "hello from base\n"; } }; struct derived : base { void f() { base::f(); std::cout << "hello from derived\n"; } };` Caution: written but not tested. – Pete Becker Jul 27 '23 at 15:24
  • @PeteBecker: that doesn't compile in GCC nor Clang: https://godbolt.org/z/811aoEfEn It seems you can't have `=0` and implementation in `{}` at the same time. – Thomas Weller Jul 27 '23 at 15:30
  • @ThomasWeller -- as I said, not tested. https://stackoverflow.com/questions/39388152/why-does-c-support-pure-virtual-functions-with-an-implementation – Pete Becker Jul 27 '23 at 15:34

0 Answers0