boost :: shared_ptr и динамическое приведение

У меня проблема с использованием shared_ptr базового класса, я не могу вызвать методы производного класса при разыменовании его. Я считаю, что код будет более подробным, чем я:

class Base : public boost::enable_shared_from_this<Base>
{
  public:
    typedef  boost::shared_ptr<BabelNet> pointer;
};

class Derived : public Base
{
  public:
     static pointer  create()
                {
                        return pointer(new Derived);
                }
     void             anyMethod()
     {
        Base::pointer foo = Derived::create();
        // I can't call any method of Derived with foo
        // How can I manage to do this ?
        // is dynamic_cast a valid answer ?
        foo->derivedMethod(); // -> compilation fail
     }

};

person HolyLa    schedule 25.11.2010    source источник
comment
Было бы полезно, если бы ваш пример был компилируемым, конечно, с прокомментированной оскорбительной строкой.   -  person Daniel Lidström    schedule 25.11.2010


Ответы (4)


см. static_cast с boost :: shared_ptr?

для получить соответствующий экземпляр shared_ptr. (соответствует dynamic_cast)

person lijie    schedule 25.11.2010
comment
Почему не static_pointer_cast? Я предполагаю, что, возможно, этот пример не является репрезентативным для реального кода, но в этом примере не требуется динамическое приведение (потому что объект имеет целевой тип) и он не допускает его (потому что ни один из классов не имеет виртуальных функций) . - person Steve Jessop; 25.11.2010
comment
Я поставил dynamic_pointer_cast из-за заголовка сообщения. Но да, в его коде подойдет static_pointer_cast. - person lijie; 25.11.2010
comment
Хорошо, благодаря вам я нашел интересную статью: nealabq.com/blog/ 26/11/2008 / pointer_cast, если я просто использую shared_ptr для производного_класса, я могу передать его как shared_ptr базовому классу, аккуратно. - person HolyLa; 25.11.2010

Общий указатель или нет, но когда у вас есть указатель на Base, вы можете вызывать только функции-члены из Base.

Если вам действительно нужно dynamic_cast, вы можете использовать dynamic_pointer_cast из boost, но есть вероятность, что не стоит. Вместо этого подумайте о своем дизайне: Derived - это Base, и это чрезвычайно сильная взаимосвязь, поэтому хорошо подумайте о Base интерфейсе и о том, действительно ли нужно знать конкретный тип.

person icecrime    schedule 25.11.2010

Если производныйMethod не объявлен в базовом классе (виртуальном или нет), то это нормально, что компиляция завершится ошибкой. Общий ptr знает и использует базовый класс (через указатель, который он содержит) и ничего не знает о производном классе и его конкретных методах.

person Cătălin Pitiș    schedule 25.11.2010
comment
Если указатель был typedef производного класса, можно ли его преобразовать с повышением, чтобы внешний класс мог знать только о Base :: pointer? - person HolyLa; 25.11.2010

Ваш код не будет работать даже с необработанными указателями.

Вам нужно либо объявить derivedMethod() метод даже в базовом классе, либо иметь указатель на объект aDerived.

person Simone    schedule 25.11.2010