假设我有一个类Handler,它有一些子类,如stringhandler,SomeTypeHandler,AnotherTypeHandler。 Handler类将方法“handle”定义为所有子类的公共接口。对于不同的处理程序,“处理”的逻辑完全不同。
所以我需要做的是将任何值传递给handle方法。然后,特定的类可以将“任何”转换为他们期望的类型。
基本上我需要的是像java类Object:D
我尝试的第一件事是void*
,但显然你不能做B* someB = dynamic_cast<B*>(theVoidPointer)
,所以那里没有运气。
我的第二个想法是使用boost::any
。但是,使用boost :: any的要求是该值必须是copy cunstructable,而不是我的数据。
有什么想法让这个工作?
由于
编辑:请注意,我知道我可以使用一个没有成员的SomeData类,让我的数据成为其子类,但我正在寻找一种更通用的方法,它不需要我自己创建包装类
答案 0 :(得分:1)
例如,您可以定义基类:
class BaseHandlerData {
...
};
然后派生您的处理程序所需的特定数据类:
class StringData: public BaseHandlerData {
...
};
class SomeData: public BaseHandlerData {
...
};
然后你应该能够将一个BaseHandlerData *参数传递给handle方法,并使用类似的东西:
void handle(BaseHandlerData *data) {
StringData* stringData = dynamic_cast<StringData*>(...);
// handle your string data here ...
}
安全地转换为您期望的数据类型。
杰拉德
答案 1 :(得分:1)
好的,这是一个使用boost :: any来保存指向数据类型的指针的简单方法。但是,请注意boost :: any会增加一些开销代码,从而略微降低性能(在大多数情况下是可以忽略的)。考虑使用boost :: spirit :: hold_any,或者如果您不需要类型安全,则使用void *。
class Handler {
public:
void handle( boost::any value ) {
do_handle( value );
}
private:
virtual void do_handle( boost::any& value ) = 0;
};
template<class T>
class HandlerBase : public Handler {
private:
void do_handle( boost::any& value ) {
// here you should check if value holds type T*...
handle_type( *(boost::any_cast<T*>( value )) );
}
void handle_type( const T& value ) = 0;
};
class StringHandler : HandlerBase<std::string> {
private:
void handle_type( const std::string& value ) {
// do stuff
}
};
现在,您可以编写许多处理程序类,派生自HandlerBase,而不假设处理的类型具有公共基类。
答案 2 :(得分:1)
另一个替代方案,即C
世界更多,将是union
类型(http://en.wikipedia.org/wiki/Union_(computer_science)#C.2FC.2B.2B)。这只允许您传递您指定的类型,而不是任何类型,但具有您描述的行为类型。
答案 3 :(得分:0)
您需要有一个名为DataObject的基类或其他东西。所有数据类型(字符串,数字,等等)都是DataObject的子类。你定义Handle是这样的:
void Handle(DataObject *dataObject);
这是一种更安全的方式来做你想要的。为了使它更好,DataObject甚至可以知道它包含哪种数据。然后处理程序可以检查他们是否已经发送了正确类型的数据。
答案 4 :(得分:-1)
你可以做到
B* someB = static_cast<B*>(theVoidPointer);