C++基础多态性

4
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

这段代码的问题在于,如果temp指向一个Product对象,那么temp->getday()是无效的。我不知道如何防止这种情况发生。如果由于某些原因,我只能在Perishable而不是Product中使用getday(),我该如何检查temp是指向一个易腐对象还是一个Product对象?
需要您的帮助,谢谢!

1
这似乎违背了多态的目的。或者我误解了你的问题。 - grep
我认为你在问“向下转型”:http://en.wikipedia.org/wiki/Downcast? - reuben
7个回答

3
“这段代码的问题在于,如果temp指向一个产品对象,temp->getday()将无效,我不知道如何防止这种情况发生。”
“为了回答这个问题,如果你绝对不想像其他答案中提到的那样在Product类中声明/实现getday(),你可以使用动态转换来确定变量的运行时类型,然后只有在有Perishable实例时才调用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()。请注意,这不再是多态的,但在运行时确定类型具有其用途,特别是如果您无法控制正在使用的对象的接口。


哦,所以dynamic_cast就像C#中的"as"关键字?我以前从未使用过dynamic_cast,一直想知道它有什么用处。 - Jonathan Henson
@Jonathan Henson 是的,它的功能基本与 C# 中的 "as" 关键字相同。我认为如果你设计好继承结构,就不太需要经常使用它。 - Bojin Li

2
我认为您需要的是这个:
class Product 
{ 
public:  
    virtual int getday() = 0;  
}  

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

有了这个改变,现在你可以做到:

cout  << temp->getday();

0
如果在Product类中,getDay是一个虚函数,那么你就不需要进行强制转换。你可以简单地这样写:
cout<< temp->getday();

如果temp指向类型为Product的对象,则将调用Product:getDay。 如果temp指向类型为Perishable的对象,并且在Perishable中被重写,则将调用Perishable::getDay,否则将调用Product::getDay
这就是运行时多态的工作原理。

我认为OP在这里并不是在询问类型转换。 - Mahesh

0
这与多态有什么关系?我假设 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

有几种方法,例如:

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

多态性需要一个虚基方法,然后在子类中覆盖该方法,就像这样:

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
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。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接