因此,我一直在阅读有关Rule of Zero的信息。
简化版:我不了解此规则的目的。 3和5的规则有点像“经验法则”,但是我看不到“经验法则”或任何其他特定意图。
详细版本:
让我引用:
这是什么意思?所有权是什么意思,所有权是什么?
他们还展示了一个示例代码(我想它与简介有关):
class rule_of_zero
{
std::string cppstring;
public:
rule_of_zero(const std::string& arg) : cppstring(arg) {}
};
他们想展示什么,我真的迷失了这一点。
此外,他们还讨论了当您处理多态类且析构函数被声明为公共(public)和虚拟时的情况,以及该块隐式移动的事实。因此,您必须将它们全部声明为默认值:
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的析构函数的基类时,您真的必须将所有其他特殊成员函数声明为默认值吗?如果是这样,我不明白为什么。
我知道这是一个地方的很多困惑。
最佳答案
零规则
零规则是关于如何编写需要使用某些资源(例如内存或其他对象)的类的另一条经验法则。在该示例中,包含字符串字符的动态分配内存是必须管理的资源。
建议让专门的类来管理资源,并仅这样做。在示例中,std::string处理所有管理已分配内存的细节。
该规则在C++ 11引入之后出现,因为该语言和标准库得到了改进,为管理动态分配的对象生存期(unique_ptr和shared_ptr)提供了更好的工具。现在,容器还允许就地构建,从而消除了动态分配的另一个原因。它可能应该被看作是对更老的三个规则的更新。
因此,如果您以前曾在构造函数中使用new来创建某些成员并在析构函数中删除,则现在应使用unique_ptr来管理该成员的生命周期,“免费”获得移动构造和移动分配。
共享指针可以记住要调用的正确的析构函数,因此对于虚拟的析构函数,通常不需要使用共享指针专门管理的对象,即使它们是多态使用的也是如此。
因此,基本上可以依赖其成员执行初始化,移动,复制和销毁所有必需操作的类,不应声明任何特殊成员函数。
五规则
与C++一样,事情并不总是那么简单。
正如斯科特·迈耶斯(Scott Meyers)所指出的,如果由于某种原因而必须添加析构函数,则即使编译器可以生成移动构造函数和移动赋值运算符,也将禁用它们的隐式生成。
然后,编译器将快乐地在各处复制您的类,而不是移动它(这可能不是您期望的那样)。例如,这可能会减慢您的程序的速度,因为必须执行更多复制。默认情况下,编译器不会对此发出警告。
因此,他建议明确指定要使用的五种特殊方法中的哪一种,以免因无关的更改而引起意外。他仍然建议编写非资源管理类,以便可以使用编译器生成的默认值。
关于c++ - 零困惑法则?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44997955/