1

我正在尝试使用模板将用 Java 编写的代码重写为 C++。这是一个例子。

代码如下所示:

class IBookUpdatedHandler {
public:
    virtual ~IBookUpdatedHandler() {}
    virtual void updateBook(int bookIndex)=0;
};

class IBookFiredHandler {
public:
    virtual ~IBookUpdatedHandler() {}
    virtual void fireBook(int bookIndex)=0;
};


template <typename T>
class Dispatcher {
private:
    list<T> listeners;
    const char* methodName;

public:
    Dispatcher(const char* name) {
        this->methodName = name;
    }

    void add(T listener) {
        listeners.push_back(listener);
    }

    void dispatch() {
        // listeners loop
        for(typename list<T>::iterator pos = listeners.begin(); pos != listeners.end(); pos++)
        {
            // i don't know what is in the box .. (list<T>)..
            // call ..
            // listener could have (*pos)->do_somethig() ?
        }
    }
};

Dispatcher<IBookUpdatedHandler*> *dispatcher = new Dispatcher<IBookUpdatedHandler*>("updateBook");
Dispatcher<IBookFiredHandler*> *dispatcher = new Dispatcher<IBookFiredHandler*>("fireBook");

我想在函数中调用 a updateBookor但是,在 C++ 中,我认为没有办法知道类型名中有什么。fireBookdispatch()

是否有与 Java 等效的 C++ getMethod

4

4 回答 4

1

您不能像在 Java 中那样在运行时选择函数。您可以使用dynamic_cast<>来确定对象的类型,然后调用适当的函数。

我认为更好的解决方案是让两个类共享相同的功能:

class IBookGenericHandler {
public:
    virtual void genericBook(int bookIndex)=0;
};

class IBookUpdatedHandler:public IBookGenericHandler {
public:
    virtual ~IBookUpdatedHandler() {}
    virtual void updateBook(int bookIndex)=0;
    virtual void genericBook(int bookIndex) { updateBook(bookIndex) }
};

class IBookFiredHandler:public IBookGenericHandler {
public:
    virtual ~IBookUpdatedHandler() {}
    virtual void fireBook(int bookIndex)=0;
    virtual void genericBook(int bookIndex) { fireBook(bookIndex) }
};

然后你可以调用genericBook你的for循环,它会处理这两个函数中的哪一个需要被调用。

于 2012-04-20T10:06:37.447 回答
0

您可以尝试使用dynamic_cast检查类型。
但是 C++ 中不存在与 Java 中相同的强大反射,您可以查看特定于实现。

无论如何,不​​确定我是否正确理解了您的问题。

于 2012-04-20T10:03:37.623 回答
0

这个问题与C++ Get name of type in template有点相关,接受的答案应该足够了,即在代码中定义一种解析器。或者你可以使用type_info

于 2012-04-20T10:04:36.927 回答
0

如果您使用最新标准(C++11,以前称为 C++0x)的功能,我建议您使用 lambda 表达式和通用函数指针:

template <typename T> 
class Dispatcher { 
private: 
    std::list<T> listeners; 
    std::function<void(T)> caller;

public: 
    Dispatcher(function<void(T)> caller) : caller(caller) {} 

    void add(T listener) { 
        listeners.push_back(listener); 
    } 

    void dispatch() { 
        // listeners loop 
        for(typename std::list<T>::iterator pos = listeners.begin(); pos != listeners.end(); pos++) 
        {
            caller(*pos);
        }
    } 
}; 

Dispatcher<IBookUpdatedHandler*> *dispatcher1 = new Dispatcher<IBookUpdatedHandler*>( 
    [](IBookUpdatedHandler* p) { p->updateBook(0); } 
); 

Dispatcher<IBookFiredHandler*> *dispatcher2 = new Dispatcher<IBookFiredHandler*>( 
    [](IBookFiredHandler* p) { p->fireBook(0); } 
); 

如果你不能使用 C++11,那么你可以使用Boost::function来代替,但它会不太清楚。

作为旁注,在大多数情况下,您应该使用std::vector而不是std::list.

于 2012-04-20T10:18:32.583 回答