我们系统的一部分使用不共享共同祖先的进程之间共享的内存。我们将C ++对象放在这个共享内存中。这些对象的方法要么在标题中内联,要么在对象库中脱节,这些对象库会链接到相应的进程中。
新来者经常对系统造成的错误是在某处引入虚拟方法。这可以保证系统崩溃,因为无法确保VT(虚拟表)驻留在每个进程的同一地址。
因此我想知道如果有人试图引入虚方法,是否有办法让编译器发出错误。类似于使复制和赋值构造函数私有以禁止复制语义。
答案 0 :(得分:4)
在提交到您的存储库时,
对于以这种方式共享的每个班级,
如果虚拟词出现在文件中
没有提交,发送电子邮件给高级开发人员,并停止违规方的工资。
答案 1 :(得分:4)
当虚拟函数出现在具有非虚析构函数的类中时,GCC(可能是其他人)会发出警告。
为所有共享类提供一个显式的非虚析构函数(什么都不做?),并将警告视为错误。
答案 2 :(得分:3)
Boost.TypeTraits提供is_polymorphic特征,但您可能需要做一些技巧才能在需要的任何地方应用它。 (例如,在基类上调用is_polymorphic
不会告诉您派生类是否引入了虚函数。)
根据您的构建系统和可用工具,您可以在那里引入支票。例如,如果我在GCC创建的目标文件上运行nm -C
,我会看到具有虚函数的简单测试类的以下输出:
0000000e T TestMe::TestMe()
00000078 T TestMe::~TestMe()
00000000 V typeinfo for TestMe
00000000 V typeinfo name for TestMe
00000000 V vtable for TestMe
所以我可以设置我的makefile(或其他)在所有目标文件上运行nm -C
,如果任何包含vtable for
则引发错误。
答案 3 :(得分:2)
要检查班级是否有虚拟方法,您可以使用boost::is_polymorphic
。
答案 4 :(得分:2)
当有人向类添加虚拟函数时,您可以使用is_polymorphic与BOOST_STATIC_ASSERT的组合来创建编译器错误。将BOOST_STATIC_ASSERT调用放在您的类的实现文件中。
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/static_assert.hpp>
#include <cassert>
class A
{
public:
/*virtual*/ void magic() {}; // making this virtual causes a compile error and a runtime error
};
using namespace boost;
int main()
{
assert( is_polymorphic<A>::value == false );
BOOST_STATIC_ASSERT( is_polymorphic<A>::value == false );
}
答案 5 :(得分:1)
你可以#define virtual Something_else
当任何人使用虚拟时会出现编译器错误,但如果没有更多工作就没有任何意义。
答案 6 :(得分:0)
这是一个(Visual Studio 2015)C ++ 11对旧问题的回答。它类似于Boost的答案。
#include <type_traits>
class foo
{
};
static_assert(!std::is_polymorphic<foo>::value, "Virtual not allowed in this class.");