views:

126

answers:

2

If I understand slicing correctly I don't think this could happen with pointers or smart pointers. For example, if you had:

class A
{
int something;
};

class B : public A
{
int stuff;
int morestuff;
};

int main()
{
    std::shared_ptr<B> b(new B());
    std::shared_ptr<A> a;
    a = b;
}

My understanding is that the block of memory allocated to the object pointed to by "b" is still the same and doesn't change when assigned to the smart pointer "a".

Please confirm or reject my understanding, or let me know of any pitfalls associated with this.

+2  A: 

You're correct, but they're not the same: you can't evaluate a->stuff.

rlbond
+5  A: 

A smart pointer is still a pointer, so such an assignment won't cause slicing. Slicing happens only when dealing with values, not pointers. Note, however, templates don't know about the relationships between the items the point at, so even though B derives from A, shared_pointer<B> doesn't derived from shared_pointer<A>, so an assignment doesn't (automatically) get an automatic up-cast like it would with native pointers.

Edit: elaborating on final point.

Slicing happens with values, not pointers, so (given your definitions of A and B), something like:

A ax = b;

would work, but would "slice" the B object to become an A object. If, however, you have some sort of template that holds an instance of the item:

template <class T>
class holder { 
   T t_;
public:
   holder &operator=(T const &t) { 
       t_ = t;
       return *this;
   }
   holder &operator=(holder const &t) { t_ = t; return *this; }
};

Now, if we try to assign one value to another, like would cause slicing:

holder<A> ha;
holder<B> hb;

A a;
B b;

ha = a;
hb = b;
ha = hb;

we will NOT get slicing. Instead, the compiler will simply give us an error, telling us that holder<A> and holder<B> are not related types, so the assignment can't happen -- without adding an explicit cast, it simply won't compile.

Jerry Coffin
Could you elaborate on the last point: **so an assignment doesn't (automatically) get an automatic up-cast like it would with native pointers**... Thanks.
AraK