2

私は次のプログラムを持っています

#include <iostream>

class Animal {
public:
    Animal(int age) : age_(age) {}
    virtual ~Animal() {}

    virtual void vocalize() = 0;
    virtual void description() = 0;
protected:
    int age_;
};

class Dog : public Animal {
public:
    Dog(int age, bool bites) : Animal(age), bites_(bites) {}
    virtual ~Dog() {}

    virtual void vocalize() {
        std::cout << "woff" << std::endl;
    }
    virtual void description() {
        std::cout << "Dog" << std::endl;
        std::cout << "age " << age_ << std::endl;
        std::cout << "bites " << bites_ << std::endl;
    }
private:
    bool bites_;

};

class Cat : public Animal {
public:
    Cat(int age, bool likes_tuna) : Animal(age), likes_tuna_(likes_tuna) {}
    virtual ~Cat() {}

    virtual void vocalize() {
        std::cout << "meow" << std::endl;
    }
    virtual void description() {
        std::cout << "Cat" << std::endl;
        std::cout << "age " << age_ << std::endl;
        std::cout << "likes tuna " << likes_tuna_ << std::endl;
    }
private:
    bool likes_tuna_;
};


int doStuff(Animal &animal) {
    animal.description();
    animal.vocalize();
}

int main() {
    Dog d(3, false);
    Cat c(5, true);

    doStuff(d);
    doStuff(c);
}

ご覧のとおり、doStuff を呼び出すときは、派生クラスを渡して基本クラス参照にバインドし、純粋仮想メソッドを呼び出して、各派生クラスによって再実装します。これらのメソッド (説明) の 1 つは、基本クラス (age_) にあるメンバー変数と、派生クラス (likes_tuna_ および bites_) にある変数の両方を使用します。私はスライスされていますか、それともこれは合法ですか? プログラムは動作しているように見えますが、たまたまかもしれません。

4

1 に答える 1

2

私はスライスされていますか、それともこれは合法ですか?

いいえ、ここではスライスしていません。

ポリモーフィズムには参照またはポインターのいずれかが必要であり、この場合は前者を使用しています。それはいいです。引数を値で渡すのではなく、参照で渡します。これにより、Animal(の引数)への参照を、実際の型がのサブクラスでdoStuff()あるオブジェクトにバインドできます。Animal

派生クラスのインスタンスを派生クラスのインスタンスにコピーしようとすると、スライスが発生します。

Animal a; // Pretend Animal is not abstract...
Dog d;
a = d; // Slicing!
Animal& a1 = d; // No slicing!
Animal* pA = &d; // No slicing!
pA = &a1; // No slicing!
于 2013-03-06T20:43:35.033 に答える