6

假设我有一个类处理程序,其中包含一些子类,如 stringhandler、SomeTypeHandler、AnotherTypeHandler。类 Handler 将方法“handle”定义为所有子类的公共接口。对于不同的处理程序,“处理”的逻辑当然是完全不同的。

所以我需要做的就是将任何值传递给 handle 方法。然后,特定的类可以将“任何东西”转换为他们期望的类型。

基本上我需要的是类似于 java 类 Object :D

我尝试的第一件事是 a void*,但显然你做不到B* someB = dynamic_cast<B*>(theVoidPointer),所以那里没有运气。

我的第二个想法是使用boost::any. 但是,使用 boost::any 的要求是该值必须是可复制的,而我的数据并非如此。

有什么想法可以让它发挥作用吗?

谢谢

编辑:请注意,我知道我可以使用一个根本没有成员的 SomeData 类,并让我的数据成为它的子类,但我正在寻找一种更通用的方法,它不需要我制作自己的包装类。

4

5 回答 5

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 派生的处理程序类,而无需假设处理的类型具有公共基类。

于 2012-04-10T15:05:00.947 回答
1

另一种更接近C世界的选择是union类型(http://en.wikipedia.org/wiki/Union_(computer_science)#C.2FC.2B.2B)。这将只允许您传递您指定的类型,而不是任何类型,但具有您描述的行为类型。

于 2012-04-10T15:24:22.353 回答
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 ...
}

安全地转换为您预期的数据类型。

杰拉德

于 2012-04-10T14:54:47.193 回答
0

您需要有一个名为 DataObject 或其他东西的基类。您的所有数据类型(字符串、数字、诸如此类)都是 DataObject 的子类。你这样定义句柄:

void Handle(DataObject *dataObject);

这是一种更安全的方式来做你想做的事。为了使它更好,DataObject 甚至可以知道它包含什么样的数据。然后处理程序可以检查是否已向它们发送了正确类型的数据。

于 2012-04-10T14:42:52.093 回答
-1

你可以做

B* someB = static_cast<B*>(theVoidPointer);
于 2012-04-10T14:42:21.143 回答