我正在尝试使用模板将用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");
我想在updateBook
函数中调用fireBook
或dispatch()
,但在C ++中,我认为无法知道typename中的内容。
是否有类似Java的getMethod
的C ++?
答案 0 :(得分: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
,它会负责调用这两个函数中的哪一个。
答案 1 :(得分:0)
您可以尝试使用dynamic_cast检查类型 但是在C ++中不存在与Java相同的强大反射,你可以看到特定的实现。
无论如何,我不确定我是否理解你的问题。
答案 2 :(得分:0)
这个问题与C++ Get name of type in template有些相关,接受的答案应该足够了,i。即在代码中定义一种解析器。您可以使用type_info
答案 3 :(得分: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
。