我正在努力清除在使用提升警告时出现在GCC和MSVC上的一些警告。我正在捕捉一个“类有虚函数,但析构函数不是这个类的虚拟实例可能无法正确破坏”在MSVC下。当启用适当的警告时,我在GCC和Clang下会收到类似的警告。我想知道投诉是什么。
相关课程有 否 析构函数(虚拟或其他;由人类创作)。其基类也是如此。该类具有堆栈分配的成员对象,但没有分配new
。该课程为template
。最后,有时,层次结构中的类被标记为“no vtable”(但这不是这种情况)。
如果我添加一个空虚拟析构函数,则清除警告。但是我想确保在不考虑上述一些限制的情况下,我不会遗漏一些不明显的东西。
以下是我与编译器和警告有关的问题:
如果上面的答案实际上是“我需要学习使用我的工具”,那么我很乐意提供空的dtors来使用分析工具。 (我认为声称这些工具并不像程序员那样聪明,所以要禁用它们。坏人可能会一直笑到银行选择开发人员无法解决的低成果......)
这是一个被警告标记的类。
template <class T>
class DL_FixedBasePrecomputationImpl : public DL_FixedBasePrecomputation<T>
{
public:
typedef T Element;
DL_FixedBasePrecomputationImpl() : m_windowSize(0) {}
// DL_FixedBasePrecomputation
bool IsInitialized() const
{return !m_bases.empty();}
void SetBase(const DL_GroupPrecomputation<Element> &group, const Element &base);
const Element & GetBase(const DL_GroupPrecomputation<Element> &group) const
{return group.NeedConversions() ? m_base : m_bases[0];}
void Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage);
void Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation);
void Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) const;
Element Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const;
Element CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const;
private:
void PrepareCascade(const DL_GroupPrecomputation<Element> &group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const;
Element m_base;
unsigned int m_windowSize;
Integer m_exponentBase; // what base to represent the exponent in
std::vector<Element> m_bases; // precalculated bases
};
以下是一些相关问题:
答案 0 :(得分:3)
有问题的类没有析构函数(虚拟或其他)。
有趣的事实:C ++中的所有对象都有一个析构函数。简单地说,如果你没有定义一个,编译器会生成它,而对于原语,它是一个无操作。
为什么编译器生成的析构函数不是虚拟的?
因为如果每个C ++程序中的每个类都有一个虚拟析构函数,人们会抱怨它会对他们的表现产生负面影响。
为什么编译器生成的析构函数不够?
完全足以破坏它所生成的类。如果有的话,摧毁它的派生类就是它不应该服务的目的。
我提供的空dtor和a之间有什么区别 默认dtor由编译器提供?
如果你没有将它定义为virtual
,那么空的dtor将禁止优化(有时),就是这样。否则,差别很明显 - 你的是virtual
(另外)。有些模板可能要求您的课程可以轻易破坏,但这并不常见。
模板是否影响编译器可以生成的内容?
没有
“没有vtable”会影响编译器可以生成什么吗?
没有
答案 1 :(得分:1)
编译器生成的析构函数不是虚拟的,除非该类具有带虚拟析构函数的基础。
原因是“零开销,如果不使用”规则 - 虚函数引入了成本,除非有一些理由使析构函数是虚拟的(例如,一个基础有一个虚拟析构函数,或程序员声明一个)析构函数不会是虚拟的。
编译器提供的空析构函数与程序员提供的析构函数之间没有区别,除非编译器生成的编译器是非虚拟的,程序员将析构函数声明为虚拟。
由于模板是编译时机制,它们会影响编译器生成和CAN生成的内容。这个问题过于笼统,无法更具体地回答。
您的上一个问题是特定于编译器的。一般来说,对于使用vtable的编译器,没有vtable的类不能具有虚函数 - 如果一个类将任何函数声明为virtual或者它继承自具有任何虚函数的类 - 它将获得vtable。在某些情况下(多重继承),该类可能有多个vtable。