我有一个类使用了几个模板化的策略.在以下示例中称为Dish.我将许多这些Dishes存储在一个向量中(使用指向简单基类的指针),但后来我想提取并使用它们.但我不知道他们的确切类型.
这是代码;它有点长,但很简单:
#include <iostream> #include <vector> struct DishBase { int id; DishBase(int i) : id(i) {} }; std::ostream& operator<<(std::ostream& out,const DishBase& d) { out << d.id; return out; } // Policy-based class: template<class Appetizer,class Main,class Dessert> class Dish : public DishBase { Appetizer appetizer_; Main main_; Dessert dessert_; public: Dish(int id) : DishBase(id) {} const Appetizer& get_appetizer() { return appetizer_; } const Main& get_main() { return main_; } const Dessert& get_dessert() { return dessert_; } }; struct Storage { typedef DishBase* value_type; typedef std::vector<value_type> Container; typedef Container::const_iterator const_iterator; Container container; Storage() { container.push_back(new Dish<int,double,float>(0)); container.push_back(new Dish<double,int,double>(1)); container.push_back(new Dish<int,int>(2)); } ~Storage() { // delete objects } const_iterator begin() { return container.begin(); } const_iterator end() { return container.end(); } }; int main() { Storage s; for(Storage::const_iterator it = s.begin(); it != s.end(); ++it){ std::cout << **it << std::endl; std::cout << "Dessert: " << *it->get_dessert() << std::endl; // ?? } return 0; }
棘手的部分在这里,在main()函数中:
std::cout << "Dessert: " << *it->get_dessert() << std::endl; // ??
我怎样才能获得甜点?我甚至不知道Dessert类型(它是模板化的),更不用说我从存储中获取的完整类型的对象了.
这只是一个玩具示例,但我认为我的代码减少了这一点.我只想传递那些Dish类,代码的不同部分将访问它的不同部分(在示例中:它的开胃菜,主菜或甜点).
解决方法
你所拥有的并不完全是基于政策的设计IMO ……如果是的话,你的班级应该实际实施(即扩展)政策.
现在,回到你的问题/例子.在您的容器中,存储“DishBase *”.对?从那时起,您将丢失集合中对象的实际类型的任何编译时信息.所以,我担心你试图做的事情显然是不可能的.
您可以做的是使用基于策略的实际设计,例如.
template<class Appetizer,class Dessert> class Dish : public DishBase,Appetizer,Main,Dessert { }
然后,您可以简单地使用dynamic_cast在运行时检查您可以将对象转换为任何具体的Appetizer / Dessert / Main.
但是从你的描述中,我得到的印象是你实际上需要抽象基类(即抽象基类可能是对你有意义的设计,而不是政策).