базовый полиморфизм с ++ - PullRequest
4 голосов
/ 20 февраля 2012
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

Проблема с этим кодом заключается в том, что если временная точка указывает на объект Product, temp-> getday () будет недействительным, и я не знаю, как этого избежать. Если из-за некоторых обстоятельств мне разрешено иметь только getday () в скоропортящихся продуктах, но не в продуктах, как я могу проверить, указывает ли temp на скоропортящийся объект или объект продукта?

Хотелось бы получить некоторую помощь /

}

Ответы [ 7 ]

3 голосов
/ 20 февраля 2012

"Проблема с этим кодом в том, что если временная точка указывает на объект Product, temp-> getday () будет недействительным, и я не знаю, как этого избежать."

В духе вопроса, и если вы абсолютно не хотите объявлять / реализовывать getday () в своем классе Product, как упомянуто в других ответах, вы можете использовать динамическое приведение, чтобы определить тип времени выполнения вашей переменной, и тогда вызывайте getday () только если у вас есть скоропортящийся экземпляр:

  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.

Итак, попробуйте динамически преобразовать вашу переменную в Perishable, и, если все прошло успешно, вы знаете, что можете вызвать getday (). Обратите внимание, что это больше не полиморфно, но определение типа во время выполнения имеет свои особенности, особенно если у вас нет контроля над интерфейсом объектов, над которыми вы работаете.

2 голосов
/ 20 февраля 2012

Я думаю, что вам нужно это:

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

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

С этим изменением вы можете сделать следующее:

cout  << temp->getday();
0 голосов
/ 20 февраля 2012
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;
   }
}

эта концепция известна как RTTI.Чтобы найти имя типа объекта temp, вы также можете использовать typeid (temp) :: name (), но это только вернет тип объекта, на который указывает temp.вы так используете dynamic_cast.

0 голосов
/ 20 февраля 2012

Полиморфизм требует виртуального базового метода, а затем переопределить метод в подклассах, например так:

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()

}
0 голосов
/ 20 февраля 2012

Есть несколько способов, например:

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

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

или

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

class Perishable : public : Product
{
public:
    virtual int getday(); // You must implement this somewhere
}
0 голосов
/ 20 февраля 2012

Какое это имеет отношение к полиморфизму? Я предполагаю, что getDay () также определен в Product? Если это так, то в этом и заключается вся цель наследования и полиморфизма. Вы должны быть в состоянии позвонить

TEMP-> getday (); без необходимости беспокоиться о броске вообще. До тех пор, пока temp действительно является Product или одним из его производных, а getDate () определяется в Product как виртуальный, никакой приведения не требуется.

Пример:

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();
}
0 голосов
/ 20 февраля 2012

Если getDay является функцией virtual в классе Product, то вам не нужно приводить.Вы можете просто написать это:

cout<< temp->getday();

Если temp указывает на объект типа Product, то будет вызываться Product:getDay.Если temp указывает на объект типа Perishable, то будет вызван Perishable::getDay, если он будет переопределен в Perishable, в противном случае будет вызван Product::getDay.

Так работает полиморфизм во время выполнения..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...