lvalue
lvalue

Reputation: 51

Do I need to respect the rule of five here?

So on https://en.cppreference.com/w/cpp/language/rule_of_three it says:

Because the presence of a user-defined (or = default or = delete declared) destructor, copy-constructor, or copy-assignment operator prevents implicit definition of the move constructor and the move assignment operator, any class for which move semantics are desirable, has to declare all five special member functions

So for this class I've done the following

#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;

}

I've seen conflicting resources online saying that if the destructor is set to default and if you don't need the other constructors you don't need to delete or define them. So what's the best course of action here?

Upvotes: 2

Views: 655

Answers (2)

Macxdmg
Macxdmg

Reputation: 11

The rule of 3 link you provided talks about the rule of 0 also. Rule of 0 takes priority over rule of 5. It also talks about how the rule of 0 is part of the C++ core guidelines.

If you're adding the destructor just to add the destructor, please reconsider applying the rule of 0. If you are attempting to stop movement / copy-ability, then you've followed the rule of 5 here and you should continue.

Upvotes: 1

user17732522
user17732522

Reputation: 76829

If you intend to default the destructor and you do not intend to make the class non-movable or non-copyable explicitly, then you should not declare the destructor at all. There is no benefit to doing that. Follow the rule-of-zero and don't declare any of the special member functions at all.

In some circumstances you need to default the destructor explicitly, specifically if you want to declare it as virtual, but otherwise leave it to behave like the implicit destructor. The issue with that is that this disables the implicit declaration of the move operations. So you should, again assuming that you do not want to intentionally disable move or copy operations, explicitly default all of the special member functions. They will still be defined as deleted if the default implementation wouldn't work. This is also in line with the rule-of-five which you quoted.

If you do this in a non-template class the compiler might warn you about the default member function being deleted if that happens. In that case you can remove or delete the offending member function to silence the warning.

If you do intend to explicitly make the class non-copyable or non-movable, then delete the relevant special member functions and default the rest.

Upvotes: 0

Related Questions