在一个C++项目中,对象很多(具有适当的行为),非面向对象结构较少(只包含数据字段而没有方法)。我希望防止这些结构被意外滥用,比如试图创建一个继承自它的类。
据我所知,因为这些“POD”(普通旧数据)结构没有虚析构函数,如果允许创建派生类对象,则无法通过POD类型的指针正确删除派生类对象。
这似乎是C++11中“final”关键字的一个很好的使用案例,它将一个类或结构标记为不可继承。
然而,我想知道“final”关键字是否会导致结构变成非POD?
我怀疑标准文档可能已经解决了这个问题,但我不够聪明去筛选出非常长的文档以找出答案。任何有用的提示都将受到欢迎。
注意:我不仅仅想知道某些编译器供应商是否通过了编译。编译通过并不能保证:
- 编译后的代码在所有情况下都能正确执行(特别是在更大、更复杂的项目中应用该技术时), - 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;
}
unique_ptr
,比容器更轻量级。几乎不可能编写一个不从析构函数中调用的异常安全的delete
表达式,而具有这样析构函数的类往往像智能指针一样。 - Potatoswatternew
和delete
。始终使用 RAII 和智能指针。 - RamblingMadstd::make_shared<MostDerived>
时,才会将正确的删除函数(针对MostDerived
)捕获到智能指针中? - rwongnew
本身通常会抛出异常,所以这种逻辑有点不一致。而且,你必须保证对象的整个生命周期中没有任何异常。在这种情况下,特别是对于 POD 对象,堆栈分配更为合适。 - Potatoswattershared_ptr
会一直记住它被初始化时的类型。为了提高效率,使用make_shared
仍然是一个好主意。对于unique_ptr
,您必须手动指定删除/清理方式,例如捕获无关的 lambda 表达式[](base *b){delete static_cast<derived *>(b);}
。 - Potatoswatter