2013-05-13 2 views
0

Я довольно новичок в умном указателе, так что извините, если мой вопрос кажется наивным для некоторых из вас. Вот пример того, что я хочу сделать:C++ smart pointers polymophism

using namespace std; 

class Base 
{ 
protected: 
    int m_Property; 
public: 
    virtual function() {...;} 
} 

class DerivedA : public Base 
{ 
public: 
    virtual function() {second implementation...;} 
    virtual functionA() {...;} 
} 

class DerivedB : virtual public Base, public DerivedA 
{ 
public: 
    virtual functionB() {...;} 
} 

void main() 
{ 
    map<int, shared_ptr<Base>> myMap; 

    shared_ptr<Base> object_ptr1 = shared_ptr<Base>(new Base()); 
    shared_ptr<Base> object_ptr2 = shared_ptr<Base>(new DerivedA()); 
    shared_ptr<Base> object_ptr3 = shared_ptr<Base>(new DerivedB()); 

    myMap.insert(pair<int, shared_ptr<Base>>(1,object_ptr1)); 
    myMap.insert(pair<int, shared_ptr<Base>>(2,object_ptr2)); 
    myMap.insert(pair<int, shared_ptr<Base>>(3,object_ptr3)); 

    // What i want to do (cause I know for sure that object_ptr3 points to a DerivedB object): 
    object_ptr3->functionB(); 
} 

Пусть говорят, что я извлек общий указатель из MyMap (назовет его myPointer), и что я хочу использовать DerivedB специфический (но не наследуются виртуальным). Скомпилированный не понимает, потому что он считает, что myPointer (или object_ptr3 в приведенном выше примере) имеет тип Base.

Я пробовал использовать его static_pointer_cast и dynamic_pointer_cast (что в некоторых случаях не работает) ... Любой лучший идентификатор для обработки этих ситуаций.

Заранее спасибо

+2

'dynamic_pointer_cast' или' static_pointer_cast' должен работать должным образом. Можете ли вы показать нам, как вы их использовали, и где это не удается? – syam

+0

«Общий» новый шаблон или только опечатка? –

+0

Вот сообщение компилятора: 1> c: \ program files \ microsoft visual studio 11.0 \ vc \ include \ memory (369): ошибка C2635: невозможно преобразовать 'Base *' в 'DerivedC *'; подразумевается преобразование из виртуального базового класса Проблема заключается в том, что у меня есть множественное наследование: DerivedC наследует от Base и DerivedA. Поэтому я использовал виртуальное, чтобы избежать проблем с двойным наследованием класса Base. – Laurent

ответ

0

dynamic_pointer_cast должны работать для этого случая. Возможно, вы сделали что-то неправильно во время кастинга.
Он должен выглядеть следующим образом:

std::shared_ptr<Base> base(new Base); 
std::shared_ptr<Derived> derived = std::dynamic_pointer_cast<Derived>(base); 

снова Глядя на ваш код, проблема может быть, что вы звоните object_ptr3.functionB(); с . вместо ->. object_ptr3 - это shared_ptr, поэтому оператор . получит доступ к членам класса shared_ptr, а не к вашему производному классу.

Также есть shared a shared_ptr?

+0

да, общий - shared_ptr. Я редактирую свой вопрос, чтобы изменить это. – Laurent

+0

Спасибо за ваш ответ. Это опечатки в моем посте. Использование, которое я сделал из shared_ptr, такое же, как в вашем коде – Laurent

Смежные вопросы