Что разрезание означает в C++?

Это упоминается в C++, сайт FAQ - "большие объекты производного класса нарезан при передаче значением как объект базового класса", что означает разрезание? Какой-либо образец для демонстрации?

http://www.parashift.com/c++-faq-lite/value-vs-ref-semantics.html#faq-31.8

Я использую 2008 VSTS + собственный C++ как моя среда разработки.

9
задан jessehouwing 29 December 2016 в 19:34
поделиться

4 ответа

Цитируя эту лекцию:

Нарезка

Предположим, что класс D является производным от класса класса C. Мы можем рассматривать D как класс C с некоторыми дополнительными данными и методами. В с точки зрения данных, D имеет все данные, которые имеет C, и возможно больше. Что касается методов, D не может скрыть ни одного метода из C, и может иметь дополнительные методы. В с точки зрения существующих методов C, единственное единственное, что может сделать D, это переопределить их своими собственными версиями.

Если x является объектом класса D, то мы можем разрезать x по отношению к C, путем отбрасывая все расширения которые превратили x в D, и сохранив только часть C. Результатом нарезки является всегда объект класса C.

нарезка http://webdocs.cs.ualberta.ca/~hoover/Courses/201/201-New-Notes/lectures/slides/slice/slide1.gif

Принцип проектирования: Нарезка объекта по отношению к родительскому классу C все равно должна давать хорошо сформированный объект класса C.

Предупреждение при использовании: Даже если D является C, вы должны быть осторожны. Если у вас есть тип аргумента, который является C, и вы D, он будет разрезан, если вы выполняете вызов по значению, указателю или ссылке. См. пример ниже.

Примечание о виртуальных функциях. Их сигнатуры используются для определения того. какую из них выполнять.

Осторожно с оператором sliced =, он может сделать lhs непоследовательным. Кроме того, оператор = никогда не является виртуальным, это не имеет смысла. Например, предположим, что классы A, B являются подклассами класса С. Просто потому, что A является C, а B является C, это не значит. означает, что вы можете присвоить объект B объекту A объекту A. Без информации о типе во время выполнения информации о типе во время выполнения вы не сможете сделать безопасное присвоение.

13
ответ дан 4 December 2019 в 10:31
поделиться

Нарезка означает, что информация о производном классе потеряна. Параметр базового класса заставляет создать объект базового класса, который имеет то же состояние базового класса, что и производный класс. Например:

struct B { int x; };

struct D : B { double y; };

void f(B b) {}

int main() {
  D d;
  f(d);
}

В функции f вы не сможете получить доступ к D :: y .

Edit: Спасибо всем за редактирование. Убедитесь, что редактирование добавляет ценности. Обратите внимание, что

  • Для структур по умолчанию используется наследование public .
  • Если вы исправите код, убедитесь, что вы обновили и тело
5
ответ дан 4 December 2019 в 10:31
поделиться

Нарезка в основном удаляет производность производного объекта класса, чтобы он вел себя так, как если бы он был объектом базового класса.

Например:

class A
{
public:
   int x;
};

class B : public A
{
public:
   int y;
};

void test(A a)
{
}

int main()
{
 B b;
test(b); // here the object b will be visible as A object in method test
//none of the B's data or methods are available.
}
1
ответ дан 4 December 2019 в 10:31
поделиться
struct A {
};

struct B : public A {
  int x;
};

void f( A a ) {
   // in here you can't access any of B's members - they have ben sliced
}

int main() {
    B b;
    f( b );   // slice!
}
1
ответ дан 4 December 2019 в 10:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: