Нарезка происходит даже после отлова по ссылке - PullRequest
1 голос
/ 02 мая 2020

Я думаю, что у моего понимания есть вмятина, и я хотел бы уточнить кое-что. Это правда, что мы всегда должны следовать золотому правилу, бросать по значению, ловить по ссылке. И если я выбрасываю производный объект и ловлю по базе, дополнительные части производного будут нарезаны. НО, когда я бросаю производный объект и ловлю базовый объект по ссылке, нарезка не должна происходить. Правильно?

Рассмотрите этот код:

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();
  }
}

Это не компилируется. Я думал, что не будет никакой нарезки, и db.d_print () вызовет d_print из Derived. Что я пропустил?

1 Ответ

1 голос
/ 02 мая 2020

Нарезка происходит даже после отлова по ссылке

Нет. Разрезание не произошло.

Ссылка ссылается на базовый подобъект брошенного производного объекта. Это по-прежнему ссылка на базу, и поэтому вы не можете ссылаться на членов производного класса. В конце концов, нет никаких гарантий, что ссылка на базу ссылается на базовый подобъект какого-либо конкретного производного класса.

Если вы хотите получить доступ к именам производного типа, вам следует перехватить ссылку на производный тип вместо. Если вы хотите иметь определенное поведение c, когда вы ловите определенный подкласс, то вы можете использовать виртуальную функцию для достижения этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...