Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;11 Java匿名回调类的替代方案 我意识到我的解决方案和C++相比还远远不够理想,所以我想问一下C++程序员在这个情况下会做什么。(C++11)_Java_C++_C++11_Callback_Abstract Class - Fatal编程技术网

C++;11 Java匿名回调类的替代方案 我意识到我的解决方案和C++相比还远远不够理想,所以我想问一下C++程序员在这个情况下会做什么。(C++11)

C++;11 Java匿名回调类的替代方案 我意识到我的解决方案和C++相比还远远不够理想,所以我想问一下C++程序员在这个情况下会做什么。(C++11),java,c++,c++11,callback,abstract-class,Java,C++,C++11,Callback,Abstract Class,我有一个对话框类,它存储一组按钮。目前,我有一个纯抽象的内部类DialogBox::Button,带有纯虚拟函数virtual void callback()const 从Java开始,我习惯于使用这个策略来创建和实例化一个匿名类,该类派生自ButtonInplace,它实现了回调函数。大概是这样的: db.add_button(new Button( "Button text", BUTTONTYPE ) { public void callback() { // Ca

我有一个
对话框
类,它存储一组按钮。目前,我有一个纯抽象的内部类
DialogBox::Button
,带有纯虚拟函数
virtual void callback()const

从Java开始,我习惯于使用这个策略来创建和实例化一个匿名类,该类派生自ButtonInplace,它实现了回调函数。大概是这样的:

db.add_button(new Button( "Button text", BUTTONTYPE ) {
    public void callback() {
        // Callback code
}});
<>这是什么促使了这个C++解决方案。 <>我的C++解决方案看起来像

dialogbox.h

class DialogBox {
public:
    // Abstract class for buttons with callback functions
    class Button;

private:
    /* ...
      stuff 
     */

public:
    /* ...
      stuff 
     */
    const std::vector< unique_ptr<DialogBox::Button> >& get_buttons() const;
    void add_button( unique_ptr<DialogBox::Button>& new_button );
};


class DialogBox::Button {

private:
    /* ...
      stuff
     */

public:
    // Constructor
    Button( const string& button_text, const DialogButtonType button_type = DialogButtonType::NORMAL );

    /* ...
      stuff
     */

    // Virtual callback function
    virtual void callback() const = 0;

};
类对话框{
公众:
//带有回调函数的按钮的抽象类
类按钮;
私人:
/* ...
东西
*/
公众:
/* ...
东西
*/
const std::vector&获取按钮()const;
无效添加按钮(唯一添加按钮和新建按钮);
};
类对话框::按钮{
私人:
/* ...
东西
*/
公众:
//建造师
按钮(常量字符串和按钮文本,常量对话框按钮类型=对话框按钮类型::正常);
/* ...
东西
*/
//虚拟回调函数
虚空回调()常量=0;
};
用法:

// Instantiate
DialogBox db{ /* ... args ... */ };
// Test adding buttons
class Button1 : public DialogBox::Button {
    using DialogBox::Button::Button;
    public: void callback() const {
        // Callback code
    }
};
std::unique_ptr<DialogBox::Button> button1{ new Button1{ "Button1", DialogButtonType::ENTER } };
db.add_button( button1 );
//实例化
对话框db{/*…args…*/};
//测试添加按钮
类Button1:公共对话框::按钮{
使用DialogBox::Button::Button;
public:void callback()常量{
//回调代码
}
};
std::unique_ptr button1{new button1{“button1”,DialogButtonType::ENTER};
db.添加按钮(按钮1);

这是有效的,但是它显然不像java版本那么干净,当然我觉得我在C++中没有做的事情。


<>那么,C++程序员怎么做呢?从概念上讲,将Button作为一个类似乎是正确的(因为它有内部数据和自己的行为)。目前,我正在考虑使用lambda表达式将回调函数传递给Button的构造函数,但我想我会在这个问题上得到一些专家的意见。

C++11解决方案是让
按钮
看起来像这样。为了简洁起见,我跳过了
字符串
对话框按钮类型
参数:

class Button {
public:
    template <typename F>
    Button(F&& f) : cb(std::forward<F>(f))
    { }

    void callback() { cb(); }

private:
    std::function<void()> cb; // type-erased functor for ANY callable
                              // that takes zero arguments
};
作为旁注,
add_按钮
应该通过值而不是引用来获取其
unique_ptr
参数

考虑一个集合:

struct Button {
  std::string name;
  std::function<void()> on_click;
};
struct按钮{
std::字符串名;
std::单击时的函数;
};

现在您可以
add_按钮({“hello”,[]{ STD::CouthToo:这不是一个好的实践。我意识到了这一点,这就是为什么我来寻找好的实践解决方案。C++版本11的C++版本有lambda函数。lambda和/或STD::函数可能有帮助。@ PauldFrErdLe:是的,它是C++ 11。你建议我用LAMBDAS来描述我的上一段吗?谢谢,这看起来不错。我也应该是吗?按值而不是按引用返回唯一ptr的向量?@JMAA按引用返回。你必须
将其移出,否则-除非这是你想要的语义,在这种情况下,当然是按值返回。为什么要有一个类
按钮
?它似乎没用。
typedef std::function按钮
——它不是真正的按钮,只是一个按钮单击时要执行的操作。@Yakk我认为该名称对某些内容有一定意义?这看起来很简单。很抱歉,noob的问题,但它允许我处理
const
按钮和其他访问控制吗?@jmaa该按钮是按值执行的,其
const
属性意味着您不能更改操作/名称,但不能更改没有别的了。
struct Button {
  std::string name;
  std::function<void()> on_click;
};