0

From past few weeks I am learning and experimenting inheritance and Polymorphism in C++.

Few syntax always confusing me to understand, mainly object calling from main function.

for eg:

#include <iostream.h>

using namespace std;

class Base
{
public:
    Base(){ cout<<"Constructing Base";}

virtual ~Base(){ cout<<"Destroying Base";}
};

class Derive: public Base
{
    public:
    Derive(){ cout<<"Constructing Derive";}

    ~Derive(){ cout<<"Destroying Derive";}
};

void main()
{
    Base *basePtr = new Derive();

    delete basePtr;
 }

Here is my question:

What actually happens when Base *basePtr = new Derive(); this syntax is called? and what are the advantages?

As per my knowledge I understood it calls derive class object and stores it in a pointer to base class object. Am I correct? If I am, why are we storing it in base class?

To clear my doubts I went through memory layout of class objects and disassembling, but it confuses me more.

Could anyone tell me how to understand this kind of syntax?

Kalyan
  • 477
  • 2
  • 6
  • 12

4 Answers4

1

When you are using pointer to a base class object instead of pointer to a derived one, you are saying that you need only BASIC properties of this derived class.

Oleg Razgulyaev
  • 5,757
  • 4
  • 28
  • 28
1

Public inheritance means that every object of the derived class IS at the same time an object of the base class (it provides all the interfaces the base class has). So, when you write:

Base *basePtr = new Derive();

new object of class Derive is created, than the pointer to it is assigned to basePtr and through basePtr you can access all the functionality Base class provides.

And if you then call any of Base class virtual functions like:

basePtr->callSomeVirtualFunction();

the function from the actual object class will be invoked, as it happens with the destructor in the end of your main function.

tkhomas
  • 103
  • 1
  • 8
0

Hmmm... Pointers are confusing at the beginning.

When you call Base *basePtr = new Derive();, you are creating a Derive object instance and just keeping a "bookmark" of where this object is, but with a Base pointer.

When you do that, the only accessible properties (without a cast) will be from Base class.

Why this is used? To abstract things. Imagine that you are coding something related to mugs, cups, glasses and jugs. Basically all types of those objects are make to store some kind of liquid. So I'll call the base class of LiquidContainer:

class LiquidContainer
{
  //...
};

class Mug : public LiquidContainer
{
  //...
};

class Glass : public LiquidContainer
{
  //...
};

class Cup : public LiquidContainer
{
  //...
};

class Jug : public LiquidContainer
{
  //...
};

All the others are inherited from LiquidContainer, although the Jug, the Cup and the Mug could be created in a little more sophisticated inheritance tree.

Anyway, the intent of having a base class and using polymorphism is to avoid code replication and to abstract thins, allowing that all the LiquidContainer family be treated almost the same way.

Take by example a more complete class definition.

class LiquidContainer
{
public:
  LiquidContainer(unsigned int capacity, unsigned int color) : 
    mCapacity(capacity), 
    mColor(color) 
  {
  }

  unsigned int getCapacity() { return mCapacity; }
  unsigned int getColor() { return mColor; }
  virtual char* name() = 0;

protected:
  unsigned int mCapacity;
  unsigned int mColor;
};

class Mug : public LiquidContainer
{
public:
  Mug() :
    LiquidContainer( 250, 0xFFFF0000 ) // 250 ml yellow mug!
  {
  }

  virtual char* name() { return "Mug"; }
};

class Glass : public LiquidContainer
{
public:
  Glass() :
    LiquidContainer( 200, 0x000000FF ) // 200 ml transparent glass!
  {
  }

  virtual char* name() { return "Glass"; }
};

class Cup : public LiquidContainer
{
public:
  Cup() :
    LiquidContainer( 50, 0xFFFFFF00 ) // 50 ml white cup!
  {
  }

  virtual char* name() { return "Cup"; }
};

class Jug : public LiquidContainer
{
public:
  Jug() :
    LiquidContainer( 1500, 0x0000FF00 ) // 1.5 l blue Jug!
  {
  }

  virtual char* name() { return "Jug"; }
};

With those class definitions you could do the following test:

#include <iostream>
#include <vector>

int main( int argc, char* argv[] )
{
  std::vector< LiquidContainer* > things;

  things.push_back( new Mug() );
  things.push_back( new Cup() );
  things.push_back( new Glass() );
  things.push_back( new Jug() );

  for ( auto container : things )
  {
    std::cout << "This is a '" << container->name() << "' with capacity of " << container->getCapacity() << "ml and color " << container->getColor() << std::endl;
  }

  return 0;
}

This little program outputs

This is a 'Mug' with capacity of 250ml and color 4294901760
This is a 'Cup' with capacity of 50ml and color 4294967040
This is a 'Glass' with capacity of 200ml and color 255
This is a 'Jug' with capacity of 1500ml and color 65280

I hope that this little exercise are enough to show you why the polymorphism is used.

y3i12
  • 21
  • 3
0

That's called Polymorphism. It means that the object is a Derive as well as Base and can be used as both. For eg. If Dog is the subclass of Animal. Object of dog can be treated as Animal too. All dogs are animal, but not all animals are dog.

So you can call a dog an animal, that's why you can give the address of subclass object(Derive) to superclass pointer(Base). But it'll remain an object of subclass and will function like one. This is just to fool compiler into understanding that it's an object of Base.

Now the benefit is you can have a method which can accept object(or pointer in precise sense) of Base class, but can be passed any of it's subclass. The con here is you can only call methods which are in the base class and may or may not overridden in derive class.

0xC0DED00D
  • 19,522
  • 20
  • 117
  • 184