所以我一直在阅读Rule of Zero。
简化版:我不明白这条规则的目的。三和五的规则有点像“经验法则”,但我不能看到“经验法则”或任何其他具有此规则的特定意图。
详细版本:
让我引用一下:
具有自定义析构函数,复制/移动构造函数或类的析类 复制/移动分配操作员应专门处理所有权。 其他类不应该有自定义析构函数,复制/移动 构造函数或复制/移动赋值运算符。
这是什么意思?什么是所有权,所有权是什么意思? 他们还展示了一个示例代码(我猜它与引言相关):
class rule_of_zero
{
std::string cppstring;
public:
rule_of_zero(const std::string& arg) : cppstring(arg) {}
};
他们想要展示什么,我真的迷失了这个。
此外,当您处理多态类并且析构函数被声明为public和virtual以及此块隐式移动的事实时,他们也在谈论场景。因此,您必须将它们全部声明为默认值:
class base_of_five_defaults
{
public:
base_of_five_defaults(const base_of_five_defaults&) = default;
base_of_five_defaults(base_of_five_defaults&&) = default;
base_of_five_defaults& operator=(const base_of_five_defaults&) = default;
base_of_five_defaults& operator=(base_of_five_defaults&&) = default;
virtual ~base_of_five_defaults() = default;
};
这是否意味着每当你有一个带有析构函数的基类被声明为public和virtual时,你真的必须将所有其他特殊成员函数声明为defaultaulted?如果是这样,我不明白为什么。
我知道这在一个地方很混乱。
答案 0 :(得分:8)
零规则
零规则是关于如何编写需要使用内存或其他对象等资源的类的另一个经验法则。在该示例中,包含字符串字符的动态分配的内存是必须管理的资源。
建议让专门的类管理资源,并且只做那些。在该示例中,std :: string负责管理分配的内存的所有细节。
该规则在引入C ++ 11之后出现,因为语言和标准库已得到改进,为管理动态分配的对象生存期提供了更好的工具(unique_ptr和shared_ptr)。此外,容器现在允许就地构造,从而消除了动态分配的另一个原因。它应该被看作是对更老的三个规则的更新。
因此,如果您之前在构造函数中使用了 new 来在析构函数中创建一些成员并 delete ,那么现在应该使用unique_ptr来管理析构函数的生命周期。会员,获得移动建设和移动任务"免费"。
共享指针可以记住要调用的正确析构函数,因此对于通过共享指针进行独占管理的对象,对虚拟析构函数的共同需求就会消失,即使它们是以多态方式使用的。
因此,基本上可以依赖其成员执行初始化,移动,复制和销毁所需的所有操作的类不应声明任何特殊成员函数。
五法则
与C ++一样,事情并不总是那么简单。
正如Scott Meyers指出的那样,如果你因任何原因必须添加析构函数,那么即使编译器可以生成它们,也会禁用隐式生成移动构造函数和移动赋值运算符。
然后编译器会愉快地将您的类复制到整个地方而不是移动它,这可能不是您所期望的。这可能会使您的程序变慢,因为必须执行更多复制。默认情况下,编译器不会对此发出警告。
因此,他建议明确指定您想要的五种特殊方法中的哪一种,以避免因无关的更改而产生意外。他仍然建议编写非资源管理类,以便可以使用编译器生成的默认值。