Question

I'm learning the hard way about object slicing, and I'm wondering if it is possible for a pointer to ever be object sliced. In other words:

  • Can pointers ever be victims of object slicing or are you always safe from object slicing as long as you're using a pointer?
Was it helpful?

Solution 2

Yes -- a pointer to base is required to be able to refer to an object of any type derived from base and still retain the correct type for the derived object (and for what it's worth, the same is true with references).

OTHER TIPS

It depends on how loosely you're willing to define "slicing". In a sense, when you point to a derived object with a base pointer (or reference), any non-virtual functions get sliced. For instance:

class A {
    void Print() { cout << "Class A\n"; }
};

class B : public A {
    void DoB() {}
    void Print() { cout << "Class B\n"; }
};

B b;
A* a = &b;
a->DoB(); // Won't compile!
a->Print(); // Prints "Class A", not "Class B"

The call to DoB doesn't work because we're using a pointer to an A, so the compiler doesn't know it can call DoB on that pointer. In this way, you're losing part of B, so you can think of this as a form of slicing.

The last line in particular is an example of a phenomenon called "name hiding". Because Print wasn't declared virtual in the base class, and our pointer is of type A, the compiler doesn't know that it should call B::Print instead of A::Print.

An important example of this problem comes into play with your destructor:

class A {
    ~A() {}
};

class B : public A {
    std::vector<int> v;
};

A* a = new B;
delete a; // What happens to B::v? Undefined behaviour!

Here, because the destructor wasn't marked as virtual, it called the base class's destructor in a non-virtual context, which means B's destructor won't get called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top