user1203499
user1203499

Reputation: 267

c++ basic polymorphism

class Product
{
...
}

class Perishable : public : Product
{
 public:
 int getday();

}


int main()
{
   Product *temp;
   //due to some coding
   //temp could point to either Perishable object or Product object that is determine           //during runtime
   cout<< ((Perishable*)temp)->getday() ;// is there other way to achieve this typecasting seems dangerous

The problem with this code is that if temp point to a Product object, temp->getday() would be invalid and i do not know how to prevent this from happening. If due to some circumstances , i am only allowed to have getday() in Perishable but not in Product, how could i check whether temp is pointing to a perishable object or a Product object?

Some help would be appreciated/

}

Upvotes: 4

Views: 200

Answers (7)

hiteshg
hiteshg

Reputation: 81

class Product 
{ 
... 
} 

class Perishable : public : Product 
{ 
 public: 
 int getday(); 

} 


int main() 
{ 
   Product *temp; 
   //due to some coding 
   //temp could point to either Perishable object or Product object that is determine           //during runtime 

   Product *pObj = dynamic_cast<Perishable *>(temp);
   if(!temp)
   {
       temp->getday();   //temp is containing Perishable Object.
   }
   else {
       //it is Product Obj;
   }
}

this concept is known as RTTI. To find the name of the type of the object temp is you can also use the typeid(temp)::name() but this will only return the type of the object temp is pointing to.. it won't do the typecasting for you so use dynamic_cast.

Upvotes: 0

Bojin Li
Bojin Li

Reputation: 5789

"The problem with this code is that if temp point to a Product object, temp->getday() would be invalid and i do not know how to prevent this from happening."

In the spirit of the question, and if you absolutely do not want to declare/implement getday() in your Product class as mentioned in the other answers, you can use dynamic cast to determine the runtime type of your variable, and then only call getday() if you have a Perishable instance:

  Product* pPerishable = new Perishable;
  Product* pProduct = new Product;
  Perishable * pActualPerishable;

  pActualPerishable= dynamic_cast<Perishable *>(pPerishable );
  //pActualPerishable will not be null because it is of type Perishable at run time

  pActualPerishable = dynamic_cast<Perishable*>(pProduct );
  //pActualPerishable will be null because you are trying to cast a runtime base type to a derived type.

So, try to dynamic cast your variable to a Perishable, and if successful then you know you can call getday(). Note this is no longer polymorphic, but determining the type at run time has its uses especially if you don't have control over the interface of the objects you are working on.

Upvotes: 3

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361252

If getDay is a virtual function in Product class, then you don't need cast. You could simple write this:

cout<< temp->getday();

If temp points to an object of type Product, then Product:getDay will be invoked. If temp points to an object of type Perishable, then Perishable::getDay will be invoked if it is overriden in Perishable, otherwise Product::getDay will be invoked.

That is how runtime polymorphism works.

Upvotes: 0

mrsheen
mrsheen

Reputation: 892

I think what you need is this:

class Product 
{ 
public:  
    virtual int getday() = 0;  
}  

class Perishable : public : Product 
{  
public:  
    virtual int getday();  
}   

With this change you can now do this:

cout  << temp->getday();

Upvotes: 2

StuartLC
StuartLC

Reputation: 107237

Polymorphicism requires a virtual base method, and then to override the method in the subclasses, like so:

class Product
{
   virtual int getday(); // You could also make this pure abstract
}

class Perishable : public Product
{
 public:
 int getday();
}

class NonPerishable : public Product
{
 public:
 int getday();
}


int main()
{
   Product *temp;
   temp = new Perishable();       
   cout << temp->getday(); // Perishable::getday()

   temp = new NonPerishable();       
   cout << temp->getday(); // NonPerishable::getday()

}

Upvotes: 0

maverik
maverik

Reputation: 5586

There are several ways, e.g.:

class Product
{
    int getday() { return ... ; } // -1 for example or any invalid value
}

class Perishable : public : Product
{
public:
    int getday();
}

or

class Product
{
    virtual int getday() = 0;
}

class Perishable : public : Product
{
public:
    virtual int getday(); // You must implement this somewhere
}

Upvotes: 0

Jonathan Henson
Jonathan Henson

Reputation: 8206

What does this have to do with Polymorphism? I am assuming that getDay() is also defined in Product? If so, then that is the entire purpose of inheritance and polymorphism. You should be able to call

temp->getday(); without having to worry about the cast at all. So long as temp is indeed a Product or one of its derivatives and getDate() is defined in Product as virtual , there is no need for any cast.

Example:

class Product
{
public:
   virtual int getday();
};

class Perishable: public Product
{
public:
  virtual int getday();   
};

int main()
{
   Product *temp; //= you should be getting the new from some factory method somewhere.

   //Polymorphism will handle making sure that the right function is called here.
   cout<< temp->getday();
}

Upvotes: 0

Related Questions