0

たとえば、C++ 関数/メソッドがある場合:

getSound(Animal a){
  a.printSound();
}

Dog次に、クラスを拡張するAnimalが動物のメソッドをオーバーライドするオブジェクトを渡します。printSound()犬のメソッドを使用する方法はありprintSound()ますgetSound()か?

クラス定義を仮想にしようとしprintSound()ましたAnimalが、まだ元の出力を取得していますprintSound()

前もって感謝します。

4

4 に答える 4

6

引数を値で受け入れるため、object-slicingが原因です。

次のように参照して受け入れます。

void getSound(Animal & a); //now reference

Animal::printSound()オブジェクトの状態を変更しない場合は、constメンバー関数にし (まだ const でない場合)、次のようにconst参照によって引数を受け入れます。

void getSound(Animal const & a); //now const reference
于 2012-08-19T16:58:17.777 に答える
5

を呼び出すとgetSound、値によって渡さAnimalれます。これは、のコピー コンストラクターDogを呼び出すことによって、 のコピーが作成されることを意味します。AnimalAnimalコピー コンストラクターはAnimal、 ではなく を構築しDogます。おそらく参照渡しが必要です:

getSound(Animal& a){
  a.printSound();
}
于 2012-08-19T16:58:43.537 に答える
5

1 つのことを除いて、基本的にすべてを正しく実行しました。

Animal オブジェクトを参照渡しするか

getSound(Animal &a);

または、問題のオブジェクトへのポインターを提供します。

getSound(Animal *a) {
    a->printSound();  //Mind the -> in this case.
}

この関数を呼び出すには、次のようにします。

Dog D;
getSound(&D);    //Passes a pointer to the function.

それ以外の場合は、実際に Dog を「渡す」のではなく、「Animal」タイプの新しいオブジェクトを構築します。

実際には、ポインター ソリューションを使用するのが最善です。そうしないと、派生オブジェクトを渡すときに問題が発生します。これは、型のオブジェクトが必要であり、Animalそれ以外では解決しないためです。

于 2012-08-19T17:00:16.403 に答える
5

仮想printSound化は正解でした。またはgetSoundを取るようにの署名を変更します。by 値を取得することにより、から新しい を構築しています。これは、 ではなく、単なるです。Animal&const Animal&AnimalAnimalDogAnimalDog

于 2012-08-19T16:57:48.757 に答える