class Pet {
public:
virtual string getDescription() const {
return "This is Pet class";
}
};
class Dog : public Pet {
public:
virtual string getDescription() const {
return "This is Dog class";
}
};
假设我有一个函数,它接受基类类型的参数,如
void describe(Base obj) {
p.getDescription();
}
我在这个函数中传递派生类对象,所以对象将被切片,我们将输出重新调整为基类。
但是,如果我修改此功能并使其像
void describe(Base& obj) {
p.getDescription();
}
并再次传递派生类对象,此时输出将是派生类。
我无法理解引用传递如何避免对象切片。
答案 0 :(得分:8)
派生对象在用于实例化基类对象时会被“切片”。传递值时会发生这种情况,因为函数参数是基类对象,而不是其他任何东西。这相当于这样做:
Derived d;
Base b = d; // b is a Base, not a Derived. It knows nothing of Derived.
引用只是对象的别名,因此对Base
对象的引用不涉及构造新的Base
对象。它只是别名一个:
Base& b = d; // b aliases d, i.e. a Derived object
在上述声明之后,b
是d
的别名,可用于多态访问d
的{{1}}界面。它可以为Base
对象设置别名,因为Derived
是 Derived
。例如,私有继承是不可能的。