4

I have a class like this:

class myClass
{
    int x[1000];
 public:
     int &getx(int i)
    {
        return x[i];
    }
}

Please note that I did not provide a move construct here.

if I use the following code:

myClass A;
auto B=std::move(a);

does A moves to B or since I did not provided a move constructor, A is copied to B?

Is there any default move constructor for an object? If yes, how it does work with pointers and dynamically allocated arrays?

mans
  • 17,104
  • 45
  • 172
  • 321

5 Answers5

3

Although you did not provide explicit move constructor, the compiler provided implicit move constructor to you.

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

  • X does not have a user-declared copy constructor, and
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared move assignment operator,
  • X does not have a user-declared destructor, and
  • the move constructor would not be implicitly defined as deleted.

So the answer on your question is: no, A is not copied to B.

It is not clear what you ask in other questions. Please specify more details.

273K
  • 29,503
  • 10
  • 41
  • 64
1

Is there any default move constructor for an object?

Yes in your case. For any type T, a move constructor is implicitly declared only if some conditions are met. More details can be seen at cpperference.com.

If yes, how it does work with pointers and dynamically allocated arrays?

The default implementation will make a shallow copies of pointers. As a consequence, more than one object will point to dynamically allocated arrays. That is going lead to problems. See The Rule of Three for more on the subject.

If you have pointers that point to dynamically allocated arrays, you need to:

  1. Provide an explicitly defined copy constructor that does the right thing with the dynamically allocated arrays. The side effect of this will be that the default move constructor will be implicitly deleted. and/or
  2. Provide an explicitly defined move constructor where you move the ownership of the dynamically allocated arrays appropriately.
R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

Move constructor is generated for your class as you don't define any method which avoid its generation (as user defined destructor or copy constructor)

The auto generated move constructor would move each member. For int[1000] it is equivalent to copy.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
0

Your question is similar to this one. Note that std::move simply is a cast. Your value a will be cast to an rvalue reference, but in your case, the original object will not be plundered or pilfered.

To use an API or an idiom correctly, you have to use it for the right thing. Moving makes most sense for e.g. class objects where the bulk of the object data is allocated on the heap. Such an object is easy to pilfer, and the 'move' can leave the pilfered object in a well-defined state. The canonical example could be e.g. some type of string class with string data on the heap.

In your case, what would you like to happen? Assume a is a local var in some function, i.e. assume a is on the stack. Assume b is a global or file scope or anonymous namespace variable, i.e. not on the stack. What would you like to happen when moving from a to b?

For a string, pilfering makes sense. For your case, pilfering is nonsensical.

Erik Alapää
  • 2,585
  • 1
  • 14
  • 25
0

If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:

  • There are no user-declared copy constructors.
  • There are no user-declared copy assignment operators.
  • There are no user-declared move assignment operators.
  • There are no user-declared destructors

then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).

Quote from cppreference

Basically, yes a default move constructor is created as long as you don't define a copy constructor, copy assignment overload, move assignment overload, or destructor. Otherwise you have to either define the behavior yourself or use: class_name ( class_name && ) = default; which will explicitly declare the default version of the move constructor.

dkneeland
  • 16
  • 1
  • 2