Как правильно получить доступ к производному объекту класса в контейнере указателя базового класса? - PullRequest
1 голос
/ 01 февраля 2012

У меня есть vector<boost::shared_ptr<Base>> объект. Я вставляю объект типа Derived, где Derived наследует Base, например: container.push_back(boost::shared_ptr<Base>(new Derived()));

Теперь я хочу вызвать функцию, которая принимает ссылку на член Derived, чтобы изменить эту последнюю запись, которую я только что вставил. Таким образом, я не создаю временный экземпляр этого Derived объекта. Вот как я могу это сделать: func(static_cast<Derived*>(&*container.back())->member);

Это выглядит очень страшно для меня. Но если я попытаюсь сделать func(static_cast<Derived>(*container.back()).member); вместо этого, компилятор скажет, что мне нужно предоставить ctor для Derived, который принимает аргументы (const Base&), чтобы преобразовать экземпляр Base в экземпляр Derived, чего я не делаю нужно сделать здесь ... Я просто хочу сослаться на мой указатель shared_ptr, как если бы это был Derived*, потому что я знаю, что это потому, что я просто new его редактировал.

Ответы [ 3 ]

3 голосов
/ 01 февраля 2012
vector<boost::shared_ptr<Base>> container;

shared_ptr<Derived> ptr(new Derived());
container.push_back(ptr);
func(ptr->member);

Нет бросков.Без временных Derived.

1 голос
/ 01 февраля 2012

Я бы использовал dynamic_cast<>, так как сохраняемый объект может не иметь тип Derived (это может быть Derived_2, также производный от Base).

func(dynamic_cast<Derived&>(*container.back()).member)

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

Примечание: dynamic_cast<>

  • если используется для приведения указателя, может возвращаться NULL
  • если используется для приведения ссылки, может выдать std :: bad_cast

Именно поэтому я предпочитаю использовать dynamic_cast со ссылками обычно. Но если вы используете его с указателем, убедитесь, что результат не NULL, прежде чем использовать его.

Изменить на обновленный вопрос:

Но если я попытаюсь сделать func (static_cast (* container.back ()). Member);

Вы хотите ссылку

static_cast<Derived&>
                  ^^^  Not the & here

Это остановит попытку вызова конструктора. Если вы static_cast <> для Derived, он попытается создать объект. То, что вы действительно хотите, это ссылка.

0 голосов
/ 01 февраля 2012

Вы можете использовать static_pointer_cast и dynamic_pointer_cast для приведения между shared_ptr с:

shared_ptr<Derived> sp = static_pointer_cast<Derived>(container.back());
...