2017-07-14 27 views
-1

Iは、アップキャストについての説明を読み、http://www.studytonight.com/cpp/upcasting.phpからダウンキャスト:アップキャストとダウンキャストがC++で使用される理由は何ですか?

[...]そのスーパークラスの参照又はポインタにサブクラスの参照またはポインタを変換する行為をアップキャストと呼ばれています。 Upcastingの逆はDowncastingで、Superクラスのリファレンスまたはポインタを派生クラスのリファレンスまたはポインタに変換します。後でDowncastingについてもっと学びます。

しかしアップキャストとダウンキャストがC++で使われている理由はわかりません。なぜこれらのメカニズムが使われているのか説明できますか?

+0

あなたが 'A * a 'を持っているなら、[良いC++の本](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – NathanOliver

+0

のように聞こえます。 (B *)a;を使用することができます。(B *)a; – user463035818

答えて

1

いくつかのクラスが継承する基本クラスを持つ場合、その派生クラスの1つを指すポインターが必要なことがよくあります。

私たちは動物のクラスを持っているし、犬と猫のクラス派生することができますたとえば:

class Animal {}; 

class Dog : public Animal {}; 
class Cat : public Animal {}; 

Dog dog; 
Animal* a = &dog; 

Cat cat; 
Animal* b = &cat; 

多くの時間を、私たちは、これらのオブジェクトの1へのポインタできるポインタを持っていると思います。 DogとCatの両方がAnimalの型であるため、Animalポインタを使用できます。これは、アップキャストの性質です。派生クラスをアップキャストし、それを基本クラスとして表現します。

ダウンキャストはどうですか?私たちはdynamic_castを使用してこれを行うことができます:

Cat c; 
Animal* animal = &c; //Implicit upcast 
Cat* cat = dynamic_cast<Cat*>(animal); //Explicit downcast 
//Check if dynamic cast worked: 
if(!cat) { 
    //ERROR: Not a cat object 
} 
+0

Dog Dogオブジェクトを直接使用することはできますが、基本オブジェクトは保持されるため、ポインタを使用する方が適しています。 「Dog dog」のような値オブジェクトをアップキャストします。 Animal a = dog; 'はオブジェクトを「スライス」させ、したがって「オブジェクトスライス」という用語を使用します。 –

+0

ありがとう!なぜ犬のポインタ "犬の星の犬"を直接使用しないでください?私は犬と犬の間に星の表記を入れようとしますが、それは表示できません。 –

+0

@SunnyLeiポインタが何かを指す必要があります。何も指さない「Dog * dog」を持っていれば、オブジェクトを持っていません。 「犬の犬」は、あなたが直接使うことができるオブジェクトです。 – Kevin

1

これらの使用の主な理由は、polymorphismを可能にすることです。多型に必要な別の技法はlate/dynamic bindingです。

アップキャスティングでは、継承したクラス(サブクラス)をベースクラスのインターフェイスで使用することができます。それは、どのような具体的な子クラスオブジェクトであるかを知る必要はなく、同じ基本クラスインタフェースを持つオブジェクトを扱うことができます。
一方、アップキャストが必要な場合は、子オブジェクトの特別なメソッドやメンバー変数を取得したい場合は、アップキャストが必要です。
キャストアップまたはキャストダウンは、dynamic_casthereと記載されています)を安全に使用できます。

キャストが成功した場合、dynamic_castはnew_type型の値を返します。キャストが失敗し、new_typeがポインタ型の場合、その型のnullポインタを返します。キャストに失敗し、new_typeが参照型である場合、型std::bad_castのハンドラに一致する例外がスローされます。ベースと子クラス間のアップまたはダウンキャストへ

オブジェクトへの唯一のビューは、具体的なオブジェクトそのものではない変更されたため、あなたはポインタ(type*)または参照型(type&)のいずれかが必要です。タイプ(type)を使用する場合は、object slicingが発生し、継承されたクラスの情報が失われます。


アップキャストとダウンキャストを使用する例を1つ挙げます。親クラスCarとから継承された2つのクラスPorscheFordがあるとします。今では別の車に入れたいところなど、std::vector<Car*> carsがあります。

std::vector<Car*> cars; 
cars.push_back(new Porsche()); /* implicit upcast */ 
cars.push_back(new Ford()); /* implicit upcast */ 

「異なる」オブジェクトのベクトルが1つあるという利点は、両方とも同じ親クラスを持つためです。

あなたは今、あなたが行うことができ、これらの車を取得したい場合は

Car*  porscheAsCar = cars.at(0); 
Porsche* porsche  = dynamic_cast<Porsche*>(cars.at(0)); 

今すぐ例えばCarクラスがdrive()方法および実装PorscheクラスdriveFast()メソッドを持っています。あなたはそれらにアクセスします。

porscheAsCar->drive(); /* Call Porsche drive() method  */ 
porsche->drive();  /* Call Porsche drive() method  */ 
porsche->driveFast(); /* Call Porsche driveFast() method */ 

の方法がvirtualで宣言されている場合、我々は、それがPorschedrive方法になります、基本クラスのインターフェイスを持つdriveメソッドを呼び出していますが。ダウンキャストでは、継承されたクラスに固有のmethods/member変数にアクセスできます。しかし、Carが実際にPorscheであり、たとえばFordでない場合にのみ可能です。

ideone see hereの一部の出力例です。

+0

ベクトルとpush_backのポインタがあります。 – Jeka

+0

@Jeka:私はそれを訂正しました。 –

0

私の謙虚な意見では、使用しているウェブサイトの品質は悪いです。私はいくつかの記事を読もうとしました。彼らは間違っているわけではありませんが、少しのプログラミング経験を持ってC++の世界に入ろうとしている人には適していません。プロのC++プログラマーとしての私のわずか15年間の経験でも、読んでも少しストレスがありました。

誰かが良い本を言ったように、無料でさえ、より良い解決策です。 Googleはあなたの親友です。これはあなたの質問に対する良い答えです。私が書くことができるものよりも完全です。https://www.tutorialcup.com/cplusplus/upcasting-downcasting.htm

いい日を過ごしてください。

関連する問題