我需要在这里遵守五法则吗?

Do I need to respect the rule of five here?

提问人:lvalue 提问时间:6/22/2022 更新时间:6/22/2022 访问量:121

问:

以此类推 https://en.cppreference.com/w/cpp/language/rule_of_three 它说:

由于存在用户定义的(或 = default 或 = delete 声明的)析构函数、复制构造函数或复制赋值运算符会阻止对移动构造函数和移动赋值运算符进行隐式定义,因此任何需要移动语义的类都必须声明所有五个特殊成员函数

因此,对于这门课,我做了以下工作

#include <string>
#include <iostream>

class Data {
private:
    std::string m_name;

public:
    Data() { m_name = "stackman"; }
    ~Data() = default;
    Data(const Data&) = delete;
    Data& operator=(const Data&) = delete;
    Data(Data&&) = delete;
    Data& operator=(Data&&) = delete;

    std::string get_name() { return m_name; }
};

int main()
{
    Data person;

    std::cout << person.get_name() << std::endl;

}

我在网上看到过相互冲突的资源,说如果析构函数设置为默认值,并且不需要其他构造函数,则不需要删除或定义它们。那么,最好的行动方案是什么?

C++ 五法则

评论

1赞 Yakk - Adam Nevraumont 6/22/2022
所以,你在问什么。“最好”是模糊的;一个意见。你是在问“我是否遵循 5 法则”?你是在问“如果我以某些方式更改此代码会发生什么”?你是在问“我试图遵循的 5 法则的后果是什么”?
1赞 Nicol Bolas 6/22/2022
这完全取决于:你是否打算让你的类不可复制和不可移动?
1赞 NathanOliver 6/22/2022
我的建议是,要明确。那么你就不需要记住任何事情了。代码会告诉你你想知道什么。
1赞 Peter 6/22/2022
由于您的类没有显式管理任何资源(它有一个成员,但正确地管理自己的资源),因此您不需要遵守五法则。零法则就足够了。不需要您拥有的构造函数或赋值运算符,除非您有特殊原因使不可复制和不可移动。std::stringstd::stringdeleteData
0赞 463035818_is_not_an_ai 6/22/2022
你没有说 .5 法则只说“如果你定义一个,那么你需要定义其他的”,但原则上用 0 法则就可以了。如果要禁用复制和移动,则无论规则 5 如何,都需要禁用它们DataData

答:

0赞 user17732522 6/22/2022 #1

如果您打算默认析构函数,并且您不打算显式地使类不可移动或不可复制,则根本不应该声明析构函数。这样做没有任何好处。遵循零法则,根本不声明任何特殊成员函数。

在某些情况下,您需要显式默认析构函数,特别是如果要将其声明为 ,但除此之外,请让它的行为类似于隐式析构函数。这样做的问题是,这会禁用移动操作的隐式声明。因此,您应该再次假设您不想故意禁用移动或复制操作,显式默认所有特殊成员函数。如果默认实现不起作用,它们仍将被定义为已删除。这也符合你引用的五分法则。virtual

如果在非模板类中执行此操作,则编译器可能会警告您默认成员函数将被删除(如果发生这种情况)。在这种情况下,您可以移除或删除有问题的成员函数以使警告静音。

如果您确实打算显式地使类不可复制或不可移动,请删除相关的特殊成员函数并默认其余函数。