我可以将final关键字应用于C++ 11中的POD(标准布局)结构吗?我是不是该?

rwo*_*ong 6 c++ inheritance struct final c++11

在一个充满对象(具有适当行为)和相对较少的非面向对象结构(仅由数据字段和无方法组成)的C++项目中,我想防止意外滥用这些结构,其中一个可能会尝试创建一个继承自它的类.

根据我的理解,因为这些"POD"(普通旧数据)结构没有虚拟析构函数,所以无法通过POD类型的指针正确删除派生类对象(如果允许创建它) .

这似乎是C++ 11"final"关键字的一个很好的用例,它将类或结构标记为不可继承.

但是,我想知道"final"关键字是否会导致结构变为非POD?

我怀疑标准文档可能已经解决了这个问题,但我没有足够的智慧来筛选很长的文档来查找.任何有用的指针都是受欢迎的.

注意:我只是不知道它通过了一些编译器供应商的编译.通过汇编不保证:

  • 编译的代码是否会在所有情况下正确执行(特别是当技术应用于更大,更复杂的项目时),
  • C++标准组织是否打算以这种方式使用它.
#include <iostream>
using namespace std;

struct Pod final
{
    int a;
    int b;
    int c;
};

#if 0
class FailsBecauseCannotDeriveFromFinalAnything : public Pod
{
};
#endif

class ContainsSomethingFinalAsMember
{
public:
    ContainsSomethingFinalAsMember() : pod() {}
private:
    Pod pod;
};

int main() 
{
    std::cout << std::is_pod < Pod > :: value << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Pot*_*ter 4

根据我的理解,因为这些“POD”(普通旧数据)结构没有虚拟析构函数,所以不可能通过 POD 类型的指针正确删除派生类对象(如果允许创建它) 。

给定原始指针是不可能的,但给定智能指针对象是可能的,例如带有适当删除器的std::shared_ptr或 a std::unique_ptr

由于智能指针已经标准化,因此几乎没有借口继续遵循delete手动使用操作符的不良做法。当然,类不应该围绕与delete运算符的兼容性来设计。每个类接口的设计都应考虑其特定用途。

不,让每个类都具有多态性或多态性并不是一个好习惯final

但是,我想知道“final”关键字是否会导致结构体变成非 POD?

不,它仍然是 POD。POD 的要求是标准布局(反过来要求没有基类、成员之间没有访问说明符、没有虚拟任何东西)和简单的特殊成员函数(复制/移动构造函数、赋值运算符、析构函数)。

然而,POD 的目的是允许您使用memcpy而不是正确构造对象,而优秀的 C++ 代码会避免这样做。

  • @rwong `shared_ptr` 将永远记住它初始化时使用的类型。为了提高效率,“make_shared”仍然是一个好主意。对于“unique_ptr”,您必须手动指定删除/清理,例如无捕获的 lambda“[](base *b){delete static_cast&lt;衍生*&gt;(b);}”。 (2认同)