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.