2012-04-15 51 views
1

我有一個對象組的模板類,其他更專業的組可以派生自(使用此組合模式)。無論如何,我的Group類會處理所有的實際組代碼。Dynamic Cast or Second Container of Objects?

現在我有一個容器存放類型爲T的對象,但我也需要通過交叉轉換來訪問另一個基類的接口。你建議我有一個容器的兩個接口或只是dynamic_cast每個對象,因爲我循環通過第一個容器?

class Sim_object { 
    add(Sim_object_sp_t object) 
    remove(Sim_object_sp_t object) 
}; 

class Group<T> : public class Sim_object { 
    add(Sim_object_sp_t object) 
    remove(Sim_object_sp_t object) 
    map<T> 
    protected iterators begin(), end() (for use by Ship_group to use for dock, attack, move functions) 
    // looking to add map<Sim_object> to prevent casting from T to Sim_object in Add/Remove but still give derived classes access to map<T> iterators. 
}; 

class IShip { 
    dock() = 0 
    attack() = 0 
    move() = 0 
}; 

class Ship_group : public Group<IShip>, public IShip { 
    dock() // uses iterators provided by Group to loop through and call dock() 
    attack() // same as dock 
    move() // same as dock 
}; 

class Ship : public Sim_object, public IShip { 
    dock() 
    attack() 
    move() 
}; 

所以我需要在組中訪問的兩個接口是T(IShip在這種情況下)和Sim_object。從組

示例:從Ship_group

template<typename T> 
void Group<T>::add(Sim_object_sp_t object) { 
    if (object->get_parent()) 
    object->get_parent()->remove(object); 

    std::tr1::shared_ptr<T> t_object = std::tr1::dynamic_pointer_cast<T>(object); 
    if (!t_object) 
    throw Error("Failed to cast to type T"); 

    objects[object->get_name()] = t_object; 
    object->set_parent(shared_from_this()); 
} 

實施例:

void Ship_group::set_destination_position_and_speed(Point destination_position, double speed) { 
    for (Iterator it = begin(); it != end(); ++it) { 
    try { 
     it->second->set_destination_position_and_speed(destination_position, speed); 
    } catch (const Error& e) { 
     cout << it->second->get_name() << " -- " << e.msg << endl; 
    } 
    } 
} 
+0

「Group」類的所有用法都需要'T'來獲得所需的接口嗎?如果是這樣,我認爲你可以編程你的'Group'模板,假設所有'T'都有所需的接口(不需要'dynamic_cast')。實例化任何類型不符合條件的類型「T」的「Group」模板類時,模板編譯器都會失敗。 – 2012-04-15 04:26:40

+0

我不確定這是否是正確的響應,但現在我從組中派生Ship_group類,其中IShip是所有類Ship對象的抽象基類。所以我真的不想污染T.我也有一個Sim_object類,該類繼承自組合模式,並執行組合函數作爲組合模式的一部分。我不想污染任何一個界面,所以我可以避免使用dynamic_cast。這是否回答你的問題? – keelerjr12 2012-04-15 04:30:08

+0

如果您可以勾畫出剛纔描述的類層次結構的框架代碼,那將會很有幫助。你可以把這個添加到你的問題嗎? – 2012-04-15 04:34:46

回答

0

也許嵌套類型內class Group<T>

class Group<T> : public class Sim_object { 
    class Specialized_Sim_Object : public T, public Sim_object {} 
    void add(Specialized_Sim_Object * object) { 
     objects[object->get_name()] = object; 
    } 
} 

shared_ptr可能沒有必要在這種情況下,要麼 - 當Ship_group迭代通過th e地圖,該類型已保證爲IShip