5

After understanding of slicing, as far as I see that it can be broken using pointers to dynamic variables. But how come? Why is there no slicing at that point ? I think myself but I'm not sure. After the ppet = pdog; assignment, pdog points to same address of ppet. Doesn't it ?

//Program to illustrate use of a virtual function 
//to defeat the slicing problem.

#include <string>
#include <iostream>
using namespace std;

class Pet
{
public:
    virtual void print();
    string name;    
};

class Dog : public Pet
{     
public: 
    virtual void print();//Keyword virtual not needed, but put
                         //here for clarity. (It is also good style!)

string breed;
};

int main()
{
    Dog vdog;
    Pet vpet;

    vdog.name = "Tiny"; 
    vdog.breed = "Great Dane";
    vpet = vdog; 

    //vpet.breed; is illegal since class Pet has no member named breed

    Dog *pdog;
    pdog = new Dog;
    pdog->name = "Tiny";
    pdog->breed = "Great Dane";

    Pet *ppet; 
    ppet = pdog; 
    ppet->print(); // These two print the same output:
    pdog->print(); // name: Tiny breed: Great Dane

    //The following, which accesses member variables directly
    //rather than via virtual functions, would produce an error:
    //cout << "name: " << ppet->name << "  breed: " 
    //     << ppet->breed << endl;
    //generates an error message: 'class Pet' has no member
    //named 'breed' .
    //See Pitfall section "Not Using Virtual Member Functions"
    //for more discussion on this.

    return 0;
}

void Dog::print()
{
    cout << "name: " << name << endl;
    cout << "breed: " << breed << endl; 
}

void Pet::print()

{
    cout << "name: " << endl;//Note no breed mentioned
}

Output:

The slicing problem:
name: Tiny
Note that it was print from Pet that was invoked.
The slicing problem defeated:
name: Tiny
breed: Great Dane
name: Tiny
breed: Great Dane
askque
  • 319
  • 2
  • 9
  • 1
    [OT]: keyword `override` is even better than write unneeded `virtual` as it check if it is really an override. – Jarod42 Dec 20 '15 at 12:34
  • 1
    I had never heard override as keyword. Could you explain little bit? @Jarod42 – askque Dec 20 '15 at 12:39
  • http://stackoverflow.com/questions/13880205/override-in-c11 – user007 Dec 20 '15 at 12:40
  • or http://en.cppreference.com/w/cpp/language/override – Jarod42 Dec 20 '15 at 12:45
  • it is really good knowledge for me thanks @Jarod42 and user007 – askque Dec 20 '15 at 13:37
  • You need to understand that a *pointer* is different from the *pointee*, i.e. the thing it points to. This is in the same way that a piece of paper with the street address of your friend is a different thing from the friend itself. You cannot make copies of your friend or painlessly remove all features from her that are not generic `Animal`, but you can very well make copies the street address, or record the street address in a log book of animals. – Kerrek SB Dec 20 '15 at 16:15
  • (I'm afraid the above metaphor will be lost on creationists and intelligent-designists.) – Kerrek SB Dec 20 '15 at 16:17

2 Answers2

3

Derived classes essentially "start" with an instance of their base classes, followed by any additional fields the derived class adds. So:

class Base {
    int a, b;
};

class Derived {
    int c, d;
};

A Derived instance looks like this in memory:

[a] [b]|[c] [d]

If you now "slice" it into a Base instance, this happens:

[a] [b]|nothing

Pointers to objects on the other hand are always the same size regardless of type, so a pointer-to-base can point to a derived object and not lose any information. The beginning of the Base part of a Derived object is exactly the same address as the Derived object itself.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
0

When you define a class, its members define its memory layout. The class data members are stored sequentially in memory.

When you derive classes and inheritance is used, the data members of the derived class are simply added after those of the base class.

Thus, when slice happens you are effectively "seeing" only the base class members.

Now, on the question "Why are pointers oto base class not slicing objects of derived class"?

One of the most important aspect of inheritance is not that it provides member functions for the derived class, but that it provides a relationship expressed between the derived class and the base class. The derived class could be seen as "a type of the base class".

For further reading check the terms upcasting and downcasting.

Upcasting is converting a derived-class reference or pointer to a base-class. In other words, upcasting allows us to treat a derived type as though it were its base type.

To answer the your questions from the comments section, "What's Override?

Deriving a function of the same name and type as a virtual function from a base class its called overriding.

Ziezi
  • 6,375
  • 3
  • 39
  • 49