C++ 即使在通过引用捕获之后也会发生切片

C++ 即使在通过引用捕获之后也会发生切片,c++,exception,C++,Exception,我认为我的理解在这里有一个凹痕,我想澄清几件事。的确,我们应该始终遵循黄金法则,按价值抛掷,按参照物捕捉。若我抛出派生对象,并按base捕获,派生对象的额外部分将被切片。但当我抛出一个派生对象,并通过引用捕获一个基础对象时,不应该发生切片。对吧? 考虑以下代码: class Base { public: void print() { std::cout << "base print" << std::endl; } }; class De

我认为我的理解在这里有一个凹痕,我想澄清几件事。的确,我们应该始终遵循黄金法则,按价值抛掷,按参照物捕捉。若我抛出派生对象,并按base捕获,派生对象的额外部分将被切片。但当我抛出一个派生对象,并通过引用捕获一个基础对象时,不应该发生切片。对吧?

考虑以下代码:

class Base {
  public:
    void print() {
      std::cout << "base print" << std::endl;
    }
};

class Derived : public Base {
  public:
    void d_print() {
      std::cout << "derived print" << std::endl;
    }
};

int main() {
  try {
    Derived d;
    throw d;
  } catch (Base& db) {
    db.print();
    db.d_print();
  }
}
类基{
公众:
作废打印(){
标准::cout
即使在通过引用捕获之后也会发生切片

没有。切片没有发生

引用引用了抛出的派生对象的基子对象。它仍然是对基的引用,因此不能引用派生类的成员。毕竟,不能保证对基的引用引用引用了任何特定派生类的基子对象


如果您想访问派生类型的名称,那么您应该捕获对派生类型的引用。如果您想在捕获特定子类时具有特定的行为,那么您可以使用虚函数来实现这一点。

如果您想要多态行为,则需要将基类方法标记为虚方法。这与ng与抛出异常有关。
派生的d;Base&b=d;b.d_print();
不起作用。没有“d_print”在 Base< /Cux>类中,这与异常无关。异常在C++中是如何工作的。如果代码中的某个函数接收了一个<代码> BASE/<代码>作为参数,它就无法调用它上面称为“代码> DyPrime<代码>的方法,因为它不存在于<代码> BASE<代码>中。NE,不是一个切片。C++是这样工作的——在代码的左侧。或<代码> ->代码>您需要一个实现该函数的对象。<代码> BASE>代码>没有实现<代码> DyPrime>代码>——实现了该函数的<代码>派生代码>。de>到a
D
。切片这个函数会更好。不是吗?--不,它不会更好。程序员完全可以通过任何方式知道传递的类型实际上是一个
派生的
,从而允许程序员选择转换为该类型。我同意切片没有发生。Wh我的观点是,请理解这一点,因为我们不允许使用d_print()在这种情况下,分割这个函数会更好。不是吗?@HemantBhargava为什么?复制基本对象有什么好处?如果对象被分割,被分割的东西之一是多态行为。对吗?这不会节省一些时间。但不是专家。实际上,我想回答一个问题stion:复制基本对象有什么缺点?@HemantBhargava切片是复制基本子对象,而不复制派生对象的其余部分。复制的缺点是它可能比不复制慢。是的。这就是我想要传达的,在这种情况下它会更慢。它会更快如果复制了基础对象,干杯!