2012-02-20 22 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 

このコードの問題は、tempがProductオブジェクトを指す場合、temp-> getday()が無効で、これを防ぐ方法がわかりません。いくつかの状況のた​​めに、私は腐敗可能な製品ではなく、製品ではないgetday()を持つことが許可されている場合、tempが壊れやすいオブジェクトまたはProductオブジェクトを指しているかどうかを確認する方法はありますか?C++の基本的な多態性

いくつかの助けをいただければ幸いです/

}

+1

これは多型性の目的を破るようです。または私はあなたの質問を誤解しています。 – grep

+0

「ダウンキャスティング」について質問していると思います。http://en.wikipedia.org/wiki/Downcast? – reuben

答えて

3

を「このコードの問題は、もし製品に一時ポイントオブジェクト、temp-> 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. 

ので、ダイナミックにしようとは生鮮にあなたの変数をキャストし、成功したならば、あなたは(getday呼び出すことができます知っている、これを注意されています、とだけあなたは生鮮インスタンスを持っている場合は()getdayを呼び出します。多態性はなくなりましたが、実行時に型を決定することは、作業中のオブジェクトのインタフェースを制御できない場合に特に役に立ちます。

+0

ああ、dynamic_castはCの "as"キーワードと似ていますか?以前はdynamic_castを使ったことが一度もありませんでした。 –

+0

@ジョナサン・ヘンソンええ、C#の "as"キーワードとほとんど同じです。私はあなたの継承構造をうまく設計すれば、多分それを使う必要はないと思います。 –

+0

ありがとうございます。それは素晴らしい作品 – user1203499

0

getDayProductクラスのvirtual機能がある場合は、キャストは必要ありません。あなたは、単純な、これを書くことができます:

cout<< temp->getday(); 

temp場合はポイントをタイプProductのオブジェクトに、そしてProduct:getDayが呼び出されます。 tempがタイプPerishableのオブジェクトを指している場合、Perishableで上書きされた場合はPerishable::getDayが呼び出されます。そうでない場合は、Product::getDayが呼び出されます。

これがランタイムポリモーフィズムの仕組みです。

+0

私はOPがここに型キャストについて質問しているとは思わない。 – Mahesh

0

多形性とは何が関係していますか?私はgetDay()もProductで定義されていると仮定していますか?もしそうなら、それは継承と多型の全目的です。

temp-> getday();電話することができるはずです。キャストについてまったく心配する必要はありません。 tempが実際にProductまたはその派生物の1つであり、getDate()がProductでvirtualとして定義されている限り、キャストは必要ありません。

例:

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のタイプを返すだけです。これはtypecastingを行いませんあなたはdynamic_castを使います。

関連する問題