继承特定于类的内存(取消)分配方法是否会使类非 POD?

Does inheriting class-specific memory (de)allocation methods make the class non-POD?

提问人:Louis Strous 提问时间:7/26/2019 最后编辑:Louis Strous 更新时间:7/26/2019 访问量:43

问:

如果 C++ POD 类继承的类除了提供特定于类的内存(取消)分配方法之外什么都不做,那么这会使 POD 类成为非 POD 吗?

例如,使用

struct Myalloc
{
   static void* operator new(size_t size);
   static void operator delete(void* p);
   // ... complete the set of operators
};

struct X : Myalloc {
  int y;
  double z;
};

是 POD 类型吗?如果它不继承,则它是 POD 类型。XMyalloc

另外,我是否需要为 定义一个虚拟析构函数?我希望不会,因为不提供数据成员,只提供静态方法。MyallocMyalloc

答案是否取决于使用哪种 C++ 标准(例如,C++03、C++11、C++17 等)?我们的代码需要在多个操作系统上编译,因此我们必须写入它们之间支持的最低 C++ 标准,即 C++03 和 C++11 的一部分。

这些问题的原因是我(不幸的是)需要让我们自己的类/结构使用我们自己的内存分配例程,并且全局替换默认内存分配例程是一个坏主意。我们的代码库有着古老的根源,其中一些代码库仍然用于扩展包含 POD 值序列的缓冲区的大小。如果该 POD 类型在我继承时变为非 POD,那么我希望我需要显式构造非 POD 值,而不仅仅是为它们分配内存。这将意味着对代码的那些古老部分进行完全重新设计,而不仅仅是用我们自己的版本替换。我现在负担不起相当多的额外时间进行全面重新设计。reallocMyallocrealloc

C++

评论


答:

3赞 NathanOliver 7/26/2019 #1

派生类不是 POD 类型。POD 类型在 C++03 中定义为

9(4):“POD-struct 是一个聚合类,它没有非 POD 结构、非 POD 联合(或此类类型的数组)或引用类型的非静态数据成员,也没有用户定义的复制运算符和用户定义的析构函数。类似地,POD 联合是一个聚合联合,它没有非 POD 结构、非 POD 联合(或此类类型的数组)或引用类型的非静态数据成员,并且没有用户定义的复制运算符和用户定义的析构函数。

由于它被定义为聚合,如果我们看一下它是如何定义的,我们有

8.5.1(1):“聚合是一个数组或类(第 9 条),没有用户声明的构造函数 (12.1),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条)和没有虚函数 (10.3)。”

我们可以看到它明确不允许使用基类。这意味着您不能拥有从其他类型派生的 POd 类型,无论该类型是否是 POD。 C++11 不会改变这一点,因为聚合仍然不能有基类。

评论

0赞 Louis Strous 7/26/2019
一个非常有用的答案,但不是我所希望的答案。
2赞 NathanOliver 8/9/2019
@LouisStrous 很抱歉回复晚了,但值得一提的是,“POD”类型可以在 C++17 中建立基础。不确定这是否会有所帮助,因为您说您需要 C++03/11 兼容性,但我想我指出了这一点。