2011-12-23 4 views
2

C++ 98로 작성된 리스너가 있다고 가정 해 봅시다.이 리스너는 추상적이며 ActionPerformed를 구현해야합니다.C++ 0x는 익명 내부 클래스를 지원합니까?

button.addActionListener(new ActionListener() { 
public void actionPerfored(ActionEvent e) 
{ 
// do something. 
} 
}); 

감사

답변

6

정확하게는 아니지만 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) 
    { 
     ... 
    } 
)); 
+4

적절한 C++ 인터페이스는 물론 그러한 "addActionListener"가 가상 함수를 재정의 (override)하지 않고 상속에 의존하지 않고'operator()'를 오버로드하는 * 적절한 * 펑터를 사용합니다. –

5

아니 당신이 그렇게 할 수 없습니다 : C에서 + +0 자바와 비슷한 할 수있는 방법이있다.

"Java와 비슷한"을 포기하고 펑터를 사용하면 C++ 11 람다가 매우 유용하다는 것을 알 수 있습니다.

+0

문제는 Java 수행 방법을 사용하는 코드가 많아서 Lambdas cant가 여기에서 도움이됩니다. – jmasterx

+0

당신은 자바 방식으로 할 수 없으므로 다른 방법을 찾아야 만합니다. 그리고 람다가 확실히 당신을 도울 수 있습니다. – Gerald

+7

Java 접근 방식을 사용하는 * C++ 코드 *가 많이 있습니까? C++을 가장하는 것은 자바가 차선책이며, 인생을 비참하게 만들 것입니다. –

5

이것은 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; 
    })); 
} 

참고.

1

나는 우리가 매크로에서이 작업을 마무리하기 위해 람다

button.addActionListener([]()->ActionListener*{ struct A: ActionListener { 
void actionPerfored(ActionEvent e) 
{ 
// do something. 
} 
}; return new A;}()); 

그것은 쉽게해야을 사용하여 C++에서이 작업을 수행 할 수 있다고 생각합니다.

+1

우리는 단지'[] {return new struct : ActionListener {...};를 할 수 없다. }'. 그건 사실 자바 버전과 많이 닮았습니다 ... – Xeo

관련 문제