2

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?

lvalue
  • 51
  • 3
  • 1
    So, what are you asking. "Best" is vague; an opinion. Are you asking "am I following the rule of 5"? Are you asking "what happens if I change this code in certain ways"? Are you asking "what are the consequences of the rule of 5 I attempted to follow"? – Yakk - Adam Nevraumont Jun 22 '22 at 02:40
  • 1
    That all depends: did you *intend* to make your class non-copyable and non-moveable? – Nicol Bolas Jun 22 '22 at 02:40
  • 1
    My advice, be explicit. Then you don't need to remember anything. The code will tell you what you want to know. – NathanOliver Jun 22 '22 at 02:42
  • 1
    Since your class doesn't explicitly manage any resources (it has a `std::string` member, but `std::string` manages it own resources correctly) you don't need to comply with the rule of five. Rule of zero is enough. There is no need to `delete` the constructors or assignment operators that you have, unless you have a particular reason to make `Data` non-copyable and non-moveable. – Peter Jun 22 '22 at 05:08
  • you didnt say whats the intended semantics of `Data`. rule of 5 only says "if you define one then you need to define others" but in principle `Data` would be fine with rule of 0. If you want to disable copies and moves then you need to disable them irrespective of rule of 5 – 463035818_is_not_an_ai Jun 22 '22 at 06:12

1 Answers1

0

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.

user17732522
  • 53,019
  • 2
  • 56
  • 105