假設我有用C++ 98構建的偵聽器,它們是抽象的,並且必須例如實現ActionPerformed。在C++ 0x中是有辦法做到這類似於Java:C++ 0x是否支持匿名內部類?
button.addActionListener(new ActionListener() {
public void actionPerfored(ActionEvent e)
{
// do something.
}
});
感謝
假設我有用C++ 98構建的偵聽器,它們是抽象的,並且必須例如實現ActionPerformed。在C++ 0x中是有辦法做到這類似於Java:C++ 0x是否支持匿名內部類?
button.addActionListener(new ActionListener() {
public void actionPerfored(ActionEvent e)
{
// do something.
}
});
感謝
不完全是,但你可以做一些與蘭姆達斯關係密切。
即:
class ActionListener
{
public:
typedef std::function<void(ActionEvent&)> ActionCallback;
public:
ActionListener(ActionCallback cb)
:_callback(cb)
{}
void fire(ActionEvent& e)
{
_callback(e);
}
private:
ActionCallback _callback;
};
..
button.addActionListener(new ActionListener(
[](ActionEvent& e)
{
...
}
));
這是C++,而不是Java,因此像Java一樣編寫C++將無法正常工作。
無論如何,你可以創建一個適配器功能。假設
typedef int ActionEvent; // <-- just for testing
class ActionListener
{
public:
virtual void actionPerformed(const ActionEvent& event) = 0;
};
然後,我們可以寫的ActionListener的模板子類,包裝了一個函數對象:
#include <memory>
template <typename F>
class ActionListenerFunctor final : public ActionListener
{
public:
template <typename T>
ActionListenerFunctor(T&& function)
: _function(std::forward<T>(function)) {}
virtual void actionPerformed(const ActionEvent& event)
{
_function(event);
}
private:
F _function;
};
template <typename F>
std::unique_ptr<ActionListenerFunctor<F>> make_action_listener(F&& function)
{
auto ptr = new ActionListenerFunctor<F>(std::forward<F>(function));
return std::unique_ptr<ActionListenerFunctor<F>>(ptr);
}
,然後用make_action_listener
包拉姆達e.g(http://ideone.com/SQaLz)。
#include <iostream>
void addActionListener(std::shared_ptr<ActionListener> listener)
{
ActionEvent e = 12;
listener->actionPerformed(e);
}
int main()
{
addActionListener(make_action_listener([](const ActionEvent& event)
{
std::cout << event << std::endl;
}));
}
注意,這絕不是地道的C++,在addActionListener()
,你應該簡單地採取const std::function<void(const ActionEvent&)>&
,甚至獲得最高效率的模板參數,並直接提供拉姆達。
我認爲,我們可以在C做++使用lambda表達式
button.addActionListener([]()->ActionListener*{ struct A: ActionListener {
void actionPerfored(ActionEvent e)
{
// do something.
}
}; return new A;}());
它應該很容易在宏來包裝這件事。
太糟糕了,我們不能'''{return new struct:ActionListener {...}; }'。這實際上看起來很像Java版本... – Xeo 2012-01-23 01:08:24
一個合適的C++接口當然會有任何這樣的「addActionListener」帶一個* proper * functor,一個重載'operator()',而不是覆蓋一個虛函數並依賴於繼承。 – 2011-12-23 18:15:04