【发布时间】:2015-09-15 16:13:13
【问题描述】:
我正在努力清除在使用提升警告时出现在 GCC 和 MSVC 上的一些警告。我在 MSVC 下捕获了一个 “类具有虚拟函数,但析构函数不是此类的虚拟实例可能无法正确销毁”。当启用适当的警告时,我在 GCC 和 Clang 下收到类似的警告。我正在尝试了解投诉的内容。
有问题的类有没有析构函数(虚拟或其他;由人类编写)。它的基类也是如此。该类具有堆栈分配的成员对象,但没有分配new。班级是template。最后,有时,层次结构中的类被标记为“no vtable”(但不是这种情况)。
如果我添加一个空的虚拟析构函数,则会清除警告。但鉴于上述一些限制,我想确保我没有遗漏一些不明显的东西。
以下是我与编译器和警告相关的问题:
- 为什么编译器生成的析构函数不是虚拟的?
- 为什么编译器生成的析构函数不够用?
- 我提供的空dtor和编译器提供的默认dtor有什么区别?
- 模板会影响编译器生成的内容吗?
- “no vtable”会影响编译器生成的内容吗?
如果上面的答案是有效的“我需要学习使用我的工具”,那么我很乐意提供空的 dtor 来使用分析工具。 (我认为声称这些工具不如程序员聪明是非常不诚实的,所以禁用它们。坏人可能会一直笑到银行采摘开发人员无法打扰的低挂果实......) .
这是带有警告标记的类之一。
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
};
以下是一些相关问题:
【问题讨论】:
-
顺便说一句,这是一个非常糟糕的界面。您的类应始终在构造函数中初始化。如果你曾经需要 Initialize() 或 IsInitialized() 之类的东西,那你就做错了。
-
@Puppy - 我认为它们实际上是内部使用的私有类,并且它们提供延迟初始化。也可以在没有组参数的情况下构造一个(例如,在用户选择的字段上生成新密钥时)。我认为该设计来自类似于 MFC 的东西,其中构造了较低的 C++ 对象,并初始化了 Windows 特定的东西。但是,它就是这样......
标签: c++ visual-c++ gcc warnings virtual-destructor