Что означает нарезка в C ++? - PullRequest
9 голосов
/ 12 марта 2010

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

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

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

Ответы [ 4 ]

13 голосов
/ 12 марта 2010

Цитирование этой лекции :

Нарезка

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

Если x является объектом класса D, то мы можем нарезать x по отношению к C,отбросить все расширения, которые сделали xa 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 являются подклассами класса C. То, что A является C, а B является C, не означает, что вы можете назначить объект B объекту A.Без информации о типе во время выполнения вы не можете сделать безопасное назначение.

4 голосов
/ 12 марта 2010

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

struct B { int x; };

struct D : B { double y; };

void f(B b) {}

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

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

Редактировать: Спасибо всем за редактирование.Пожалуйста, убедитесь, что редактирование добавляет ценность.Обратите внимание, что

  • Для structs наследование по умолчанию - public.
  • Если вы исправите код, убедитесь, что вы тоже обновили тело
1 голос
/ 12 марта 2010

Слайсинг - это, в основном, удаление производности объекта производного класса, который ведет себя так, как если бы это был объект базового класса.

Например:

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 голос
/ 12 марта 2010
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!
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...