Приведет ли это к нарезке объектов? - PullRequest
0 голосов
/ 11 марта 2012

Скажем, у меня есть массив указателей на абстрактный класс:

Piece *pieces[2]; // where piece is an abstract class

И у меня есть два класса, расширяющих Piece, называемых King и Queen.Я присваиваю King точке в pieces и Queen другой точке:

pieces[0] = new King();
pieces[1] = new Queen();

Если оператор перегрузки не перегружен, происходит ли нарезка?Или pieces[0] является экземпляром King, а pieces[1] является экземпляром Queen?Что происходит в этом массиве (если это был C ++)?

РЕДАКТИРОВАТЬ: см. Полный пример кода здесь .

Ответы [ 3 ]

4 голосов
/ 11 марта 2012

На самом деле это не компилируется: вы не можете присвоить King * (тип выражения new King) для Piece (тип выражения *pieces[0]).

Чтобы ответить на ваш подразумеваемый вопрос, хотя:

Piece *piece = new King(); // fine, no slicing, just assigning a pointer
*piece = Queen();          // oops, slicing - assigning a Queen to a Piece

В массиве вашего вопроса, предполагая, что вы написали pieces[0] = new King; и т. Д., Вы просто храните два Piece указателя, один из которых указывает на King, а другой - на Queen.

1 голос
/ 11 марта 2012

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

0 голосов
/ 30 сентября 2013

Да будет нарезка.

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

Помните, что это тот случай, когда вы не следуете принципам ООП. Директор говорит,

"When you are deriving from any class you should not change the interface. 
The reason for inheritance is moving from generic to specific type, and not
 providing new functionality."

И, если вы следуете этому принципу, то поведение нарезки можно определить как

“Moving from specific behaviour to more general behaviour”. 

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

NOTE:- Slicing always does not happen in case of private inheritance. 
If you try to do so it will result in compilation error.
(For more information on private inheritance:-http://stackoverflow.com/questions/19075517/object-slicing-in-private-inheritance/19083420?noredirect=1#19083420)
...