2010-11-25 4 views
13

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

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 
    } 

}; 
+1

Это помогло бы, если бы ваш пример был компилируемым, конечно, с оскорбительной строкой, прокомментированной. – 2010-11-25 14:26:04

ответ

18

см static_cast with boost::shared_ptr?

вам нужно использовать dynamic_pointer_cast, чтобы получить соответствующий shared_ptr экземпляра. (соответствует dynamic_cast)

+1

Почему бы не `static_pointer_cast`? Я думаю, что, возможно, пример не является репрезентативным для реального кода, но в этом примере не требуется динамическое преобразование (потому что объект имеет целевой тип) и не позволяет его (поскольку ни один из классов не имеет каких-либо виртуальных функций) , – 2010-11-25 14:03:32

1

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

+0

Если указатель был typedef производного класса, может ли он быть вздутым, чтобы внешний класс мог знать только о Base :: pointer? – HolyLa 2010-11-25 14:12:32

0

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

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

4

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

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