Given this code:
#include <iostream>
class base {
private:
char x;
public:
base(char x) : x(x) {
std::cout << "base::base(char) " << this << std::endl;
}
base(base&& rhs) {
std::cout << "base::base(base&&), moving from " << &rhs << " to " << this << std::endl;
x = rhs.x; rhs.x = '\0';
}
virtual ~base() {
std::cout << "base::~base " << this << std::endl;
}
};
class child : public base {
private:
char y;
public:
child(char x, char y) : base(x), y(y) {
std::cout << "child::child(char, char) " << this << std::endl;
}
child(child&& rhs) : base(std::move(rhs)) {
std::cout << "child::child(child&&), moving from " << &rhs << " to " << this << std::endl;
y = rhs.y; rhs.y = '\0';
}
virtual ~child() {
std::cout << "child::~child " << this << std::endl;
}
};
int main(int argc, char* argv[]) {
{ // This block enables me to read destructor calls on the console...
base o = child('a', 'b');
}
std::cin.get();
return 0;
}
In the stack frame of main
there's an area where child
is being instantiated. After that the move constructor of base
is being called with a reference to the newly created child
. The (move) construction of base
takes place in a different area in the same stack frame and copies the parts of child
which are derived from base
. From now on all that's left of child
is the base
parts, making it nothing more than base
.
I know that polymorphism is not possible for objects on the stack and I think I understand why: Efficiency. No vtable lookups and such. The compiler can choose the methods to call at compile time.
What I don't understand is: Why is it possible to assign a child
instance to a base
variable (in a stack frame) when everything that makes up child
gets lost? What's the motivation for that? I'd expect a compile error or at least a warning, because I can't think of a good reason to allow it.