The Object slicing issue:
If you take a super class and assign it the value of a subclass only the members that are part of the super class get copied over  (default assignment operator behavior). 
Consider the following:
#include <iostream>
using namespace std;
class Super {
public:
   int a;
   Super(): a(0) { }
   Super(int _a): a(_a) { }
   virtual void dump() {
        cout << "A is : " << a << std::endl;
   }
};
class Child: public Super {
public: 
   int b;
   Child(int _a, int _b): b(_b), Super(_a) { } 
   virtual void dump() {
        Super::dump();
        cout << "B is : " << b << std::endl;
   }
};
int main() {
    Child c(5, 10);
    Super s;
    s.dump();  // A is 0
    s = c;
    s.dump();  // A is 5 (but there is no B in s 
               // so calling Child::dump would be nonsensical
}
So as you can see that calling the child dump is nonsensical when the child value is assigned to the parent; because there is no "b" in the parent context.
Note that a statement like:
        c = s; 
is non-sensical because while parentage is deterministic (Child is the type of Super so the implicit operator Super& Super::operator=(const Super&) applies to the derived Child class the reverse isn't true; i.e. Child& Child::operator=(const Child&) does not make sense in context of Super
The reference issue
Okay so the confusion comes in from understanding what a reference variable is.  A reference variable is a synonym for whatever it is initialized with.  You can use the reference variable exactly like the original. 
In your case:
   ss.print(); 
is the same as 
   c.print();
"
To see this more explicitly, consider the following snippet:
int foo;
int& bar = foo;
// bar is now a reference to foo so the following will sets foo to 67
bar = 67;
std::cout << foo <<std::endl;