C におけるポリモーフィズムとスライス
C では、ポリモーフィズムを使用して、派生クラスに基づいてさまざまな機能を持つオブジェクトを作成できます。ただし、慎重に扱わないと、奇妙な動作が発生する可能性があります。そのような問題の 1 つは「スライス」です。
次のコードを考えてみましょう:
#include <iostream> using namespace std; class Animal { public: virtual void makeSound() { cout << "rawr" << endl; } }; class Dog : public Animal { public: virtual void makeSound() { cout << "bark" << endl; } }; int main() { Animal animal; animal.makeSound(); Dog dog; dog.makeSound(); Animal badDog = Dog(); badDog.makeSound(); Animal* goodDog = new Dog(); goodDog->makeSound(); }
得られる出力は次のとおりです:
rawr bark rawr bark
出力は次のようになると予想されます。 「rawr bark bark bark」ですが、代わりに、オブジェクト badDog は犬ではなく動物として動作します。これはスライスによるものです。
BadDog を Animal badDog = Dog() として作成すると、Dog オブジェクトを Animal にスライスすることになります。これは、badDog には Animal クラスの一部である Dog の部分のみが含まれており、Dog の特定の機能はすべて失われていることを意味します。
これを修正するには、ポインターまたは参照を使用してクラスを派生する必要があります。ポインターまたは参照はオブジェクトをコピーしないため、特定の機能を保持できます。たとえば、goodDog ポインターは、その Dog 機能を正常に保持しています。
Java などの一部の言語にはデフォルトで参照セマンティクスがありますが、C では値セマンティクスが使用されます。 C では、参照セマンティクスを実現するには、ポインターまたは参照を明示的に使用する必要があります。そうしないと、 badDog の例で示されているように、スライスの問題が発生する可能性があります。
以上がスライスは C のポリモーフィズムにどのような影響を与えますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。