【问题标题】:Pass by reference avoids object slicing通过引用传递避免对象切片
【发布时间】:2015-03-10 07:00:29
【问题描述】:
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";
    }
};

假设我有一个函数,它接受 bas 类类型的参数,如

void describe(Base obj) {
   p.getDescription();
}

我在这个函数中传递派生类对象,所以对象将被切片,我们将得到与基类相关的输出。

但是如果我修改这个函数,让它像

void describe(Base& obj) {
   p.getDescription();
}

再次传递派生类对象,这次输出将是派生类的。

我不明白按引用传递如何避免对象切片。

【问题讨论】:

  • 虽然不完全正确,但引用基本上只是一个花哨的指针。所以当你传递一个引用时,你实际上是传递了一个指向 actual 对象的指针。
  • 你真的不只是问切片问题是什么吗?
  • 不,我知道对象切片的概念。我通过参考感到困惑,但现在得到了答案:)
  • What is object slicing? 的可能重复项
  • 跟引用传递有关..

标签: c++


【解决方案1】:

派生对象在用于实例化基类对象时会被“切片”。当您按值传递时会发生这种情况,因为函数参数是基类对象,而不是其他任何东西。相当于这样做:

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

在上述语句之后,bd 的别名,可用于多态访问dBase 接口。它可以给Derived 对象起别名,因为Derived is-a Base。这在私有继承中是不可能的。

【讨论】:

  • 技术上可以使用私有继承,参见 [class.access.base]/3
猜你喜欢
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 2018-01-02
  • 2015-03-18
  • 2020-04-06
相关资源
最近更新 更多