What is the state of an object after it has been moved - through a reference to its base class?
Let's assume there is a hierarchy of two classes:
class Base {};
class Foo: public Base {};
Which are used as follows:
Foo foo;
Base &base = foo;
Base moved = std::move(base);
In what state foo
after such a move? Does the Standard provide any requirements for restrictions on such code?
source to share
The standard makes no such requirement for move constructors for C ++ classes that are not part of the standard library. The library writer can do whatever he wants. For components that are part of the standard library, the C ++ 17 standard says something (focus)
Β§ 20.5.5.15 Moving from the library types state [lib.types.movedfrom]
Objects of types defined in the C ++ standard library can be moved from (15.8). Move operations can be specified explicitly or implicitly generated. Unless otherwise noted, such relocated objects are placed in a valid but undefined state.
For standard library classes that are part of the inheritance hierarchy, you will need to consult the documentation to see what happens when you try to move the construct of the base object out of the base class. rvalue refers to a derived class object. So if you could point out which class in particular bothers you, I might try and help more.
Not sure how relevant this is to your question, but in regards to what will actually happen in such a constructor. Remember that the virtual function mechanism is disabled in the constructors for the object to be created, but not for the referenced object. In the following example
class Base {
public:
virtual vector<int> extract_vector() { ... }
// Move constructor can use virtual functions on the other object
Base(Base&& other) {
this->vec = other.extract_vector();
}
private:
std::vector<int> vec;
};
class Foo : public Base {
public:
vector<int> extract_vector() override { ... }
private:
// this does something Β―\\_(γ)_/Β―
SpecialVectorAdaptor<std::vector<int>> vec;
};
The virtual function extract_vector
on other
in the move constructor for will be called Base
, and you can use virtual methods on the object other
. But you cannot use such virtual methods for the class to be created.
In short , the behavior of the code you've shown will depend solely on the implementation of the classes in question.
source to share
In your particular case, nothing happens as both Base
and Foo
are empty classes.
For a more interesting situation that, as Base
well as Foo
have some movable elements (or base), as Base
has a user-defined motion designer will use the default constructor move. This will move the Base
piece Foo
in moved
, but leave it intact. For example, after
struct Base { std::unique_ptr<int> X; };
struct Foo: Base { std::unique_ptr<int> Y; };
Foo foo;
foo.X.reset(new int);
foo.Y.reset(new int);
Base &base = foo;
Base moved = std::move(base);
foo.X
empty ( nullptr
) with original value moved to moved
, but still foo.Y
still retains its original value.
This demonstrates that when navigating away from a link, you are potentially changing the state of the referenced object, which can create all sorts of unwanted effects and is best avoided.
source to share