c++ 0x支持匿名内部类吗?

Does C++0x support Anonymous Inner Classes?

本文关键字:匿名内部类 支持 0x c++      更新时间:2023-10-16

假设我有c++ 98内置的侦听器,它们是抽象的,必须例如实现ActionPerformed。在c++ 0x中是否有类似于Java的方法:

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 )
   {
       ...
   }
));

不,你不能这么做。

如果你放弃"类似于Java",而只使用函子,你会发现c++ 11 lambda非常有用。

这是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包装lambda,例如(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&)>&,甚至是模板参数以获得最大效率,并直接提供lambda。

我认为我们可以在c++中使用lambdas

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