1

Consider following MWE: reference.cpp:

#include <iostream>

class A {
    public:
        virtual void foo() = 0;
};

class B : public A {
    public:
        void foo() override {
            std::cout << "test";
        }
};

If I run clang-tidy on that, clang-tidy -checks="cppcoreguidelines-virtual-class-destructor" ./reference.cpp -- I'll get expected output:

42 warnings generated.
/workspace/test/reference.cpp:3:7: warning: destructor of 'A' is public and non-virtual [cppcoreguidelines-virtual-class-destructor]
class A {
      ^
/workspace/test/reference.cpp:3:7: note: make it public and virtual
class A {
      ^
/workspace/test/reference.cpp:8:7: warning: destructor of 'B' is public and non-virtual [cppcoreguidelines-virtual-class-destructor]
class B : public A {
      ^
/workspace/test/reference.cpp:8:7: note: make it public and virtual
class B : public A {
      ^
Suppressed 40 warnings (40 in non-user code).

Let's fix A:

#include <iostream>

class A {
    public:
        virtual void foo() = 0;
        virtual ~A() = default;
};

class B : public A {
    public:
        void foo() override {
            std::cout << "test";
        }
};

And run clang-tidy again:

40 warnings generated.
Suppressed 40 warnings (40 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.

So, A is fixed, but there's still no virtual destructor in B. And no warning. How do I fix it?

PS:

clang-tidy --version
LLVM (http://llvm.org/):
  LLVM version 14.0.5
  Optimized build.
  Default target: x86_64-redhat-linux-gnu
  Host CPU: skylake
Roman
  • 1,396
  • 4
  • 15
  • 39
  • After fixing `A`, `B`'s destructor is implicitly declared and virtual, see [Are virtual destructors inherited?](https://stackoverflow.com/questions/2198379/are-virtual-destructors-inherited), especially sub-question 2, and [cppreference on virtual destructors](https://en.cppreference.com/w/cpp/language/virtual#Virtual_destructor), so I would consider clang tidy to be correct about not warning anymore. The CppCoreGuidelines rule [is explicitly about base classes](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-dtor-virtual). – He3lixxx Jul 27 '23 at 21:38

1 Answers1

3

Destructors of derived class are automatically virtual if any base class destructor is virtual.

Adding it manually to the derived class would be redundant and potentially a pessimization, because it would prevent the implicit declaration of move special member functions.

user17732522
  • 53,019
  • 2
  • 56
  • 105