Нарезка на унаследованные объекты

Следующие случаи указывают на проблему срезов:
Во время выполнения задания:
https://stackoverflow.com/a/274634/640639

Во время вызова функции:
Что такое нарезка объектов?

Мой вопрос: не решены ли оба этих случая, если оператор присваивания и конструктор копирования объявлены виртуальными, а производный класс соответствующим образом скопирует необходимые данные? Если это так, то в принципе передача по значению все еще должна работать в этих случаях, верно?

3

Решение

Очевидно, вы не можете объявить конструкцию копии virtual: Объекта пока нет. Вы можете отключить конструкцию копирования, хотя.

Тем не менее, делая назначение virtual все еще не работает, потому что при нарезке объектов статический тип назначенного объекта все еще является просто базовым классом. Он никогда не станет производным классом, независимо от того, какой тип вы ему назначаете.

0

Другие решения

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

Виртуального конструктора не существует, так как virtual означает «зависит от динамического типа this«, и до запуска конструктора объект даже не существует, поэтому он не может иметь производный динамический тип.

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

Если вы хотите иметь возможность копировать по значению, но при этом иметь полиморфное поведение, вы можете создать объект, который содержит указатель на другой объект и который клонирует объект в его конструкторах и операторах присваивания (используя что-то вроде value_ptr из библиотеки Колес Мартиньо Фернандеса):

class Base {
public:
virtual Base* clone() const = 0;
virtual void do_stuff() = 0;
};

class CopyablePolymorphic {
public:
CopyablePolymorphic(Base* base) : ptr(base) {}
private:
value_ptr<Base> ptr;
};

class Derived1 : public Base {
public:
virtual Base* clone() const {
return new Derived1(*this);
}
virtual void do_stuff() {
//Derived1 stuff
}
};

class Derived2 : public Base {
public:
virtual Base* clone() const {
return new Derived2(*this);
}
virtual void do_stuff() {
//Derived2 stuff
}
};

//etc...
4

По вопросам рекламы [email protected]