0

私は C++ を勉強しています。ランタイム ポリモーフィズムを理解するのに問題がありますか? クラスのオブジェクトを作成することで同じ作業ができるのに、なぜ参照/ポインターを使用する必要があるのですか?

`例:

class A{
private:
    int p;
public:
    A(){}   //ctor
    void Print(){}
    void display(){}
    void showrecord(){}
} 
class B:public A
{
Private:
     int q;
public:
    B(){}    //ctor
    void Print(){}  
    void displayrecord(){}
}

上記の場合、オブジェクトを使用してBクラスの任意のメソッドにアクセスでき、スコープ解決を使用してAクラスメソッドbにアクセスできるのに、なぜポインターを使用してオブジェクトをそれに割り当てるのですか?

4

3 に答える 3

1

あなたが3台の異なる車を持っているとしましょう。そして、それらを駆動するさまざまなメカニズムがあります。ドライバーは、基礎となるエンジンについて知る必要はなく、車を運転する方法のプロトコルのみを知る必要があります。つまり、このペダルを踏んで加速し、そのペダルを踏んでブレーキをかけるなどです。

ドライバーの観点からは、ホンダ、フォード、ビュイックのいずれであっても問題ありません。彼から見ればただのだ。同様に、車が駐車されている小屋がある場合、それらを car shed と呼びます。それは車を収容し、それぞれが何であるかについて気にしません。そう

std::vector<Car*> v;
v.push_back(new Ferrari());
v.push_back(new Honda());
v.push_back(new Ford());

クラスのオブジェクトを作成することで同じ作業ができるのに、なぜ参照/ポインターを使用する必要があるのですか?

ポインターまたは参照がなければ、共通性があっても特定の意味で異なるオブジェクトのコレクションを作成することはできません。これは、Java、C# などの一部の厳密な OOP 言語では、すべてのオブジェクトを という基本クラスから派生させることで回避されObjectます。C++ はマルチパラダイム言語であり、プログラマーは自分のプロジェクトに適した決定を自由に行うことができます。C++ でこれを行う方法は、基本クラスのポインターを使用することです。このイディオムは、ランタイム ポリモーフィズムと呼ばれます。

for (const auto &this_car : v)
     this_car->drive();

ここでは、実際のメーカーに関係なく、基本クラスが型の一部であるv限り、ベクターは車を保持できます。car同様に、drivemake ごとに異なりますが、それを呼び出す関数がそれを知っている必要はありません。

編集:

この投稿が実際には質問に答えていないことを指摘してくれた nijansen に感謝します: なぜポインターまたは参照 (動的型) がランタイム ポリモーフィズムに必要なのですか? 彼らはそれを達成するために使用したと言っているだけで、通常の(静的型)変数を使用できない理由は説明していません。

C++ は、オブジェクトの型が手元にあるだけで、コンパイル時に完全に認識される場合と認識されない場合があるように設計されています。はタイプであることがCircle c;わかっています。一方では、どのオブジェクトが指しているのか本当にわかりません。自身の型は ですが、指しているオブジェクトの具象型は不明です。私たちが知っているのは、 から派生した何らかのオブジェクトを指していることだけです。動的または自動メモリ割り当てと混同しないでください。これは、自動変数でも同じです。ここでも孤立して、コンパイラーは、オブジェクトがどの具体的な型であるかを認識していません。cCircleShape *p = make_shape();ppShape*ShapeShape *p = &c;pp

p静的(非ポインター、非参照)型として記述した場合、Shape p = make_shape();またはスライスShape p = c;で実際に起こること、つまり具象型になり、ポインターではないため、オブジェクトの(形状)部分をそれにコピーします。ほとんどの場合望ましくありません。pShapeCirclec

基礎となる型を知らずに、適切な具体的な型の関数をどのように呼び出すのでしょうか? C++ は、ジョブを実行するための仮想関数を提供します。これが、ランタイム ポリモーフィズムが常に C++ の仮想メソッドで説明される理由です。Java や C# などの言語では、すべてのメソッドが仮想であり、すべてのオブジェクト型が参照/ポインターです。あなたの質問への答えは、ランタイムポリモーフィズムのために参照/ポインター変数が必要になるように言語が設計されているということです

于 2013-10-07T10:46:36.693 に答える
0

一般的な例を挙げると、

擬似コードを許してください。しばらくして Cpp コードを追加しますが、今は少し錆びています

スーパークラス

Class Animal
{

}

サブクラス

Class Dog : public Animal
{

}

Class Cat : public Animal
{

}

別のクラス、

class Vet 
{
    void checkAnimal(recieve Animal)
    {

    }          
}

今、この使用法を考えてみましょう。

vetObject.checkAnimal(dogObject);
vetObject.checkAnimal(catObject);

ポリモーフィズムがなければ、Vet クラスは次のようになります。

class Vet 
{
    void checkAnimal(recieve Cat)
    {

    }          

    void checkAnimal(recieve Dog)
    {

    }          

     ....  and so on
}
于 2013-10-07T10:51:22.707 に答える
0

これにより、すべてのオブジェクトに対していくつかの一般的なプロセスを実行できます。たとえば、あなたにはChicken : Animalクラスがあり、あなたにはCow : Animalクラスがあり、それらには共通の機能doSlaughter()があり、あなたにはSlaughterHouseJobクラスがあります。メソッドを処理したい場合はslaughterHouseJob.doSlaughterAnimals()、次のコードを書くだけです。

for(Animal animal:animals){
    animal.doSlaughter(); //It can be chicken or Cow or other animals. Simply one function for all jobs
}
于 2013-10-07T10:53:05.010 に答える