It seems to me you are not familiar with what std::move
actually does.
As others have said, std::move
doesn't actually move anything. It obtains an xvalue
(a variable that has a name, but can have its resources reused or transfered to another object) reference from an lvalue
(essentially a named variable), so, std::move
is nothing but a cast. It doesn't create any new object. Read more about it here and here.
Still about move semantics topic,
std::move
is mostly useful so that you can force rvalue-aware methods to receive and reuse resources in variables that you absolutely know that can have their resources moved.
To get a more indepth insight of this, I'd recommend reading What are move semantics?. For instance, one of its uses is creating an object from a temporary (e.g, objects created inside a function and then returned):
#include <vector>
#include <iostream>
class A {
public:
// A very large resource
std::vector<int> resource;
// Constructs our very large resource
A(): resource(1024, 0) { std::cout << "Default construct" << std::endl; }
// Move (reuses) a very large resource from an instance
A(A && other) : resource(std::move(other.resource)) {
std::cout << "Move construct" << std::endl;
}
};
Now, A
's move constructor is only called when the other
object is an rvalue
(or an xvalue
), such as:
A foo(A a) { return a; }
int main() {
A a = foo(A());
return 0
}
In this scenario, before foo()
gets called, a temporary A()
is created and passed in as argument. foo()
returns it, but since it is a temporary , it fits as an rvalue
and is passed to the move constructor of A
when constructing A a = foo(A())
.
Inside the move constructor of A()
, std::move(other.resource)
is used when constructing another resource
to call the move constructor of std::vector
so that it can try to use whatever it can from other.resource
instead of creating everything from scratch again (and then copying).
But as stated previously, std::move
on itself doesn't move anything, but it is there to convey intent to move, help the compiler do the right thing (and other programmers to read it and understand faster what you meant).
So, to answer your question directly, no, there isn't anything that'd let you transform an object into another, other than constructing a new object. If you are sure that you are going to destroy obj
(which you are not doing, by the way), you can implement an constructor of D2
that accepts an rvalue
of D1
:
class D2 {
public:
D2(D1 && d1) : resource(std::move(d1.resource)) { d1.resource = nullptr; }
}
int main() {
D1 * obj = new D1();
D2 * obj2 = new D2(std::move(*obj));
delete obj;
}
There are other things to consider when doing this, though, such as destructors of moved objects and other details. I'd recommend reading more about the subject and also maybe using a different method of achieving what you are doing, such as the Strategy pattern mentioned in another answer.