2012-02-20 72 views
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 

這段代碼的問題是,如果臨時指向一個Product對象,temp-> getday()將是無效的,我不知道如何防止這種情況發生。如果由於某些情況,我只允許getday()在易腐爛但不在產品中,我如何檢查temp是否指向易腐物品或產品對象?C++基本多態性

一些幫助,將不勝感激/

}

+1

這似乎打敗了多態性的目的。或者我誤解了你的問題。 – grep 2012-02-20 05:24:09

+0

我想你是在問「downcasting」:http://en.wikipedia.org/wiki/Downcast? – reuben 2012-02-20 05:26:33

回答

3

「這段代碼的問題是,如果溫度點的產品對象,temp-> getday()將是無效的,我不知道如何防止這種情況發生。「

在問題的精神,如果你絕對不想申報/實施getday()作爲在其他的答案中提到你的產品類,則可以使用動態轉換,以確定您的變量的運行時類型,然後只調用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. 

所以,儘量動態投你的變量易腐,如果成功的話,那麼你知道你可以調用getday()請注意,這是。不再是多態,但在運行時確定類型有其用處,尤其是在您無法控制正在處理的對象的界面時。

+0

哦,所以dynamic_cast就像C#中的「as」關鍵字?我從來沒有使用過dynamic_cast,並總是想知道它是如何有用的。 – 2012-02-20 05:47:20

+0

@Jonathan Henson是的,它的功能與C#中的「as」關鍵字非常相似。我認爲如果你很好地設計你的繼承結構,你可能不需要太多地使用它。 – 2012-02-20 06:00:58

+0

謝謝。它效果很好 – user1203499 2012-02-20 06:33:27

0

如果getDayProductvirtual功能,那麼你並不需要強制轉換。你可以簡單的寫:

cout<< temp->getday(); 

如果tempProduct類型的對象,然後Product:getDay將被調用。 如果temp指向Perishable類型的對象,則Perishable::getDay將在Perishable中被覆蓋時調用,否則將調用Product::getDay

這就是運行時多態性的工作原理。

+0

我不認爲OP在這裏詢問類型轉換。 – Mahesh 2012-02-20 05:25:10

0

這與多態性有什麼關係?我假設getDay()也是在產品中定義的?如果是這樣,那麼這就是繼承和多態的完整目的。你應該可以撥打

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

Polymorphicism需要虛擬基方法,然後覆蓋在該方法子類,如下所示:

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

} 
2

我想你需要的是這樣的:

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

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

隨着這一變化,你現在可以這樣做:

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