C++ 98로 작성된 리스너가 있다고 가정 해 봅시다.이 리스너는 추상적이며 ActionPerformed를 구현해야합니다.C++ 0x는 익명 내부 클래스를 지원합니까?
button.addActionListener(new ActionListener() {
public void actionPerfored(ActionEvent e)
{
// do something.
}
});
감사
C++ 98로 작성된 리스너가 있다고 가정 해 봅시다.이 리스너는 추상적이며 ActionPerformed를 구현해야합니다.C++ 0x는 익명 내부 클래스를 지원합니까?
button.addActionListener(new ActionListener() {
public void actionPerfored(ActionEvent e)
{
// do something.
}
});
감사
정확하게는 아니지만 Lambdas와 가까이 할 수 있습니다.
즉 :
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에서 + +0 자바와 비슷한 할 수있는 방법이있다.
"Java와 비슷한"을 포기하고 펑터를 사용하면 C++ 11 람다가 매우 유용하다는 것을 알 수 있습니다.
이것은 Java가 아닌 C++이므로 Java와 같이 C++을 작성하는 것이 효과가 없습니다.
어쨌든 어댑터 기능을 만들 수 있습니다. 람다, 예컨대 (http://ideone.com/SQaLz)을 래핑하는 make_action_listener
를 사용하여 다음
#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);
}
과 :
typedef int ActionEvent; // <-- just for testing
class ActionListener
{
public:
virtual void actionPerformed(const ActionEvent& event) = 0;
};
그런 다음 우리는 함수 객체를 래핑 된 ActionListener의 템플릿 서브 클래스를 작성할 수 가정 해 봅시다. 이것은 당신이 단순히 const std::function<void(const ActionEvent&)>&
을, 또는 최대 효율도 템플릿 매개 변수, 직접 람다를 제공해야 addActionListener()
에서 관용적 C++, 거리가 멀다는 것을
#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;
}));
}
참고.
나는 우리가 매크로에서이 작업을 마무리하기 위해 람다
button.addActionListener([]()->ActionListener*{ struct A: ActionListener {
void actionPerfored(ActionEvent e)
{
// do something.
}
}; return new A;}());
그것은 쉽게해야을 사용하여 C++에서이 작업을 수행 할 수 있다고 생각합니다.
우리는 단지'[] {return new struct : ActionListener {...};를 할 수 없다. }'. 그건 사실 자바 버전과 많이 닮았습니다 ... – Xeo
적절한 C++ 인터페이스는 물론 그러한 "addActionListener"가 가상 함수를 재정의 (override)하지 않고 상속에 의존하지 않고'operator()'를 오버로드하는 * 적절한 * 펑터를 사용합니다. –