в несколько разных производных классов. Мне нужно, чтобы контейнер содержал указатели базового класса, чтобы позволить это.

отрим следующую схему:

class Base { /* ... */ };

class Derived : public Base
{
public:
    void AdditionalFunctionality(int i){ /* ... */ }
};

typedef std::shared_ptr<Base> pBase;
typedef std::shared_ptr<Derived> pDerived;

int main(void)
{
    std::vector<pBase> v;
    v.push_back(pBase(new Derived()));

    pDerived p1(  std::dynamic_pointer_cast<Derived>(v[0])  ); /* Copy */
    pDerived p2 = std::dynamic_pointer_cast<Derived>(v[0]);    /* Assignment */

    p1->AdditionalFunctionality(1);
    p2->AdditionalFunctionality(2);

    /* A */

    return 0;
}

Здесь я расширяю базовый класс производным классом, который добавляет функциональность (AdditionalFunctionality метод).

Первый вопрос, это нормально? Я прочитал много вопросов, которые говорят, что это нехорошо, и вы должны объявить дополнительную функциональность в базовом классе (часто предлагается сделать их чистыми виртуальными методами в базовом классе). Однако я не хочу этого делать. я бы хотелпростираться функциональность базового класса, а не просто реализовать его по-другому. Есть ли лучшее решение для достижения этой цели?

Итак, в этом коде я также использую контейнер STL для хранения этих указателей, что позволяет мне хранить указатели как на объекты типа Base, так и на объекты типа Derived, не разрезая объекты.

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

Если я «знаю», что определенный указатель на производный объект, я тогда используюstd::dynamic_pointer_cast навести умный указатель.

Третий вопрос, он компилируется без предупреждения и работает, но безопасно ли это? Действительно? Будет ли это нарушать аспект подсчета ссылок общих указателей и не сможетdelete мои объекты илиdelete их, прежде чем я ожидаю?

Наконец, я могу выполнить это приведение, используя конструктор копирования или присваивание, как показано для p1 и p2. Есть ли предпочтительный / правильный способ сделать это?

Похожие вопросы:

Понижать shared_ptr <Base> до shared_ptr <Derived>? : Это очень близко, однако класс dervied не добавляет дополнительной функциональности, как мой, поэтому я не уверен, что он полностью такой же. Кроме того, он используетboost::shared_ptr где я используюstd::shared_ptr (хотя я понимаю, что boost пожертвовал shared_ptr в библиотеку std, поэтому они, вероятно, одинаковы).

Спасибо за помощь.

Редактировать:

Одна из причин, по которой я спрашиваю, заключается в том, что я понимаю, что можно сделать следующее (неправильно):

    /* Intentional Error */
    v.push_back(pBase(new Base()));
    pDerived p3( std::dynamic_pointer_cast<Derived>(v[1]) );
    p3->AdditionalFunctionality(3); /* Note 1 */

Где я пытаюсь уменьшить указатель на объект Base до указателя на производный объект, а затем вызвать метод, который реализован только в классе Derived. Другими словами, объект, на который указывает объект, не определяет (или даже не «знает» о методе).

Это не поймано компилятором, номай вызвать segfault в зависимости от того, какAdditionalFunctionality определено.

Ответы на вопрос(3)

Ваш ответ на вопрос