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 时,我将派生类传递给绑定到基类引用,然后调用纯虚方法,并由每个派生类重新实现。其中一种方法(描述)使用基类(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 回答