英文:
Clang tidy does not detect missing virtual destructor
问题
请参考以下 MWE 代码:
reference.cpp:
#include <iostream>
class A {
public:
virtual void foo() = 0;
};
class B : public A {
public:
void foo() override {
std::cout << "test";
}
};
如果我在这上面运行 clang-tidy,命令如下:clang-tidy -checks="cppcoreguidelines-virtual-class-destructor" ./reference.cpp --
,我将获得如下期望的输出:
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).
让我们修复 A:
#include <iostream>
class A {
public:
virtual void foo() = 0;
virtual ~A() = default;
};
class B : public A {
public:
void foo() override {
std::cout << "test";
}
};
然后再次运行 clang-tidy:
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.
所以,A 已经修复了,但是 B 中仍然没有虚析构函数,也没有警告。要如何修复它?
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
英文:
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
答案1
得分: 3
派生类的析构函数如果任何基类析构函数是虚拟的,就会自动变为 virtual
。
在派生类中手动添加它将会是多余的,可能会导致性能下降,因为这会阻止隐式声明移动特殊成员函数。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论