如何将“任何类型的数据”传递给C ++中的函数

时间:2012-04-10 14:38:25

标签: c++ pointers boost-any

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

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

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

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

我的第二个想法是使用boost::any。但是,使用boost :: any的要求是该值必须是copy cunstructable,而不是我的数据。

有什么想法让这个工作?

由于

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

5 个答案:

答案 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);