#c #binary-tree
#c #двоичное дерево
Вопрос:
У меня есть два класса
class Base {
explicit Base();
virtual void update();
}
class Derived : Base {
std::shared_ptr<Base> left, right;
explicit Derived(std::shared_ptr<Base> left, std::shared_ptr<Base>);
virtual void update() override;
void special_update();
}
Я могу создать производный объект из двух указателей на объекты базового класса. Но я также хотел бы создать производный объект из двух указателей на объекты производного класса. Есть хороший способ сделать это?
Комментарии:
1. Вы можете использовать,
dynamic_cast
чтобы проверить, относится лиleft
параметр в конструкторе кDerived
классу или к какому-либо другомуBase
классу.2. Вы знаете, почему используете
explicit
модификатор в своих конструкторах, или вы просто всегда так делаете?3. Также: судя по именам классов и разделяемому,
update()
похоже, чтоDerived
предполагается, что это подклассBase
. Но ваш код этого не показывает.Derived
Предполагается, что это подклассBase
или нет?4. ДА. Я действительно намерен создать производный класс, производный от Base. Я отредактировал код.
5. @AnthonyMBenedict Вы также предполагаете, что это будет частное наследование или общедоступное наследование?
Ответ №1:
Предполагая, что вы намереваетесь Derived
быть классом, публично производным от Base
, вы ищете, std::static_pointer_cast
который может преобразовать std::shared_ptr
одного типа в std::shared_ptr
другого типа:
Derived(std::shared_ptr<Derived> left, std::shared_ptr<Derived> right)
: Derived(
std::static_pointer_cast<Base>(left),
std::static_pointer_cast<Base>(right)) {
}
Если вы не знали, что тип всегда будет конвертируемым в Base
из-за отношений наследования, вы также могли бы использовать std::dynamic_pointer_cast
(например, при приведении из Base
в Derived
).
Также обратите внимание, что вам, очень, очень вероятно, понадобится иметь virtual ~Base() {}
, если вы собираетесь перетаскивать Derived
объекты в std::shared_ptr<Base>
objects. В противном случае вы, скорее всего, понесете убытки.
Если Derived
и Base
на самом деле совершенно не связаны, то ответ — нет.
Если у вас частное наследование, вам придется создать свою собственную версию static_pointer_cast
:
// in Derived:
static std::shared_ptr<Base> static_pointer_cast(std::shared_ptr<Derived> constamp; r) noexcept {
return std::shared_ptr<Base>(r, r.get());
}
Комментарии:
1. Нет необходимости использовать приведение для преобразования производного в базовый.
return std::shared_ptr<Base>(r, static_cast<Base*>(r.get()));
не сработает, вы не можете создать два общих указателя, которые указывают на один и тот же объект, не зная об этом друг друга (вы, возможно, захотите посмотреть наstd::enable_shared_from_this
это)2. @n.’местоимения’m. Почему вы это говорите? Обратите внимание, что первым аргументом
std::shared_ptr
являетсяr
исходный объект. Взгляните на документацию дляshared_ptr
конструктора (8) .3. Извините, не заметил конструктор псевдонимов.