What are the precedents (if any) to make a class irrevocable?

Consider the classic approach to make the class incompatible:

// similar to boost::noncopyable class noncopyable { protected: constexpr noncopyable() = default; noncopyable(const noncopyable&) = delete; noncopyable& operator=(const noncopyable&) = delete; }; class c: private noncopyable { /* ... */ }; 

As the declaration of any copy operation prevents the automatic creation of move operations, it automatically makes all derived classes immovable (by default) as well (so the noncopyable full name will be noncopyable_and_nonmoveable ).

Now let's look at the classic unpublished classes from the standard library, for example. unique_ptr . It is not copyable, but movable, otherwise its utility will be limited. I believe this is true for many other cases.

In fact, I cannot come up with any example when a class should be executed without moving. My argument is that even if the class is not planned to be moved there, this can be done with an error that can be harmful.

There are actually two related questions:

1) Why is boost::noncopyable also not moving? This causes problems:

 struct c: private boost::noncopyable { std::unique_ptr<Something> something; c(c&&) = default; c& operator=(c&&) = default; }; 

not working ( wandbox ) - move operations cannot be generated because they are not generated for the base class. You need to execute them manually → list your members → maintenance → errors. Just unlocking the move operations in noncopyable will solve the problem.

2) What are the uses when portability is harmful, so should it be prevented?

+5
source share
3 answers

The immovable gives you more control over the identifier of the property.

If an object moves, its address may change:

 moveonly a; b = std::move(a); 

Now anyone who has a reference to a points to an obsolete object or (something else completely).

Other situations when this occurs is when you have external logic depending on the identity of the object ("address stability"), if you want, for example, with pthread mutexes: Move the constructor for std :: mutex

Addition . The scoped_XXXX naming scoped_XXXX often used to refer to non-movable types (for example, types that guarantee that an instance of an instance is immutable). Contrast this, for example. unique_XXXX , which implies a unique instance that can move. Note , however, the standard library did not fully accept this naming convention: Example: std::lock_guard<> vs std::unique_lock<> . C ++ 17 changes this a bit

+8
source

1) Why is boost :: noncopyable also not moving?

Most likely, historical reasons. boost::noncopyable should work with pre-C ++ 11 compilers. In fact, there are very few reasons to inherit from boost::noncopyable when using C ++ 11 and later. If it was moveable in C ++ 11, how can we establish the same move semantics in C ++ 03 compilers?

2) What are the uses when portability is harmful, so should it be prevented?

non-moveablity should apply to the types of resources that are supposedly provided to you as an external system. For example, synchronization primitives, objects that represent things like your computer ACPI platform, etc.

+2
source

Why can't boost :: noncopyable also be moved?

From the C ++ 11 standard:

If the definition of class X does not explicitly declare the move constructor, it will be declared implicitly as the default, if and only if

- X does not have a copy constructor declared by the user,

- X does not have a user-declared copy destination operator,

- X does not have a user-defined move destination operator,

- X does not have a user-declared destructor and

- the move constructor will not be explicitly defined as remote.

So, I suppose that when you delete copy c'tor and / or copy, you prohibit declaring the default move constructor.

What are the uses when portability is harmful and should therefore be prevented?

The first thing that comes to my mind is objects that depend on their location in memory space, for example mutex es.

0
source

Source: https://habr.com/ru/post/1272498/


All Articles