See the following code:
#include <iostream>
#include <chrono>
class Parent
{
public:
Parent() = default;
virtual ~Parent() = default;
Parent(const Parent& pr) : i{pr.i} {std::cout << "Parent copy constructor\n";}
Parent& operator=(const Parent& pr) {std::cout << "Parent copy assignment\n"; this->i = pr.i; return *this;}
Parent(Parent&& pr) : i{std::move(pr.i)} {std::cout << "Parent move constructor\n";}
Parent& operator=(Parent&& pr) {std::cout << "Parent move assignment\n"; this->i = std::move(pr.i); return *this;}
virtual void print_i_j() = 0;
int i = 10;
};
class Child : public Parent
{
public:
Child() = default;
Child(const Child& cr) : Parent{cr}, j{cr.j} {std::cout << "Child copy constructor\n";}
Child& operator=(const Child& cr) {std::cout << "Child copy assignment\n"; this->j = cr.j; return *this;}
Child(Child&& cr) : Parent{std::move(cr)}, j{std::move(cr.j)} {std::cout << "Child move constructor\n";}
Child& operator=(Child&& cr) {std::cout << "Child move assignment\n"; Parent::operator=(std::move(cr)); this->j = std::move(cr.j); return *this;}
void print_i_j() {std::cout << "i = "<< i << " j = " << j << std::endl;}
int j = 100;
};
int main(int argc, const char * argv[])
{
Child c;
c.i = 30;
c.j = 300;
c.print_i_j();
Child c2; // leave c2 with defaults (i=10, j=100)
Parent& p_ref = c2;
p_ref.print_i_j();
c2.j = 150;
p_ref.print_i_j();
p_ref = std::move(c); // (1)
p_ref.print_i_j(); // (2)
return 0;
}
When I run this I get:
i = 30 j = 300
i = 10 j = 100
i = 10 j = 150
Parent move assignment
i = 30 j = 150
As far as I can tell, as indicated in this output, i
changes as a result of moving an instance of the derived class into a reference to the parent class, but j
does not.
Is the result printed in (2) an indication that the move in (1) caused slicing? Or is some other behavior (or even undefined behavior) kicking in?