0

私は全体的なクラスを定義しようとしています。それを「コマンド」と呼びます。これは、実行するコマンドを定義する「列挙型アクション」を取ることができます。このクラスで可能なコマンドを表現したいと思います (各コマンドの変数を格納します) が、一般的な Command クラスから継承するコマンドごとにクラスを定義したくありません。

たとえば、クラス Command は、実行するコマンドを定義する「enum Action」を定義します。start の場合は int と char* が格納され、「setResolution」のような場合は幅と高さの 2 つの int が格納されます。

このクラスで任意のコマンドを表現できるようにしたいのですが、これを実現するための最適なオブジェクト指向の方法がわかりません。私の OO は非常にさびており、継承を伴わない解決策を見つけることができないようです。ありがとうございました。

4

1 に答える 1

2

あなたの説明は、 と を組み合わせた機能によく似ていstd::functionますstd::bind。これらを使用すると、渡す必要のあるすべての引数を格納する呼び出し可能な関数オブジェクトが作成され、特定の詳細を知らなくても呼び出しを実行できます。メンバー関数とフリー関数の両方で動作します。Commandクラスを要件を説明する単純なラッパーに変更できます。

以下の例では、フリー関数を使用してこれを行います。クラスは、引数やそのCommand型を気にしません。気にするのは、コマンド自体がどのようにディスパッチされるかだけです。

#include <iostream>
#include <functional>
#include <string>

class Command
{
public:
    Command(const std::string& name, const std::function<void()>& func)
        : name_(name), func_(func) {}

    Command(const Command& o) : name_(o.name_), func_(o.func_) {}

    void operator()()
    {
        std::cout << "executing " << name_ << std::endl;
        func_();
    };

    const std::string name() const { return name_; }

private:
    Command& operator=(const Command&);

    const std::string           name_;
    const std::function<void()> func_;
};

void start(int a, const char* b)
{
    std::cout << "start(" << a << "," << b << ")" << std::endl;
}
void setResolution(int a, int b)
{
    std::cout << "setResolution(" << a << "," << b << ")" << std::endl;
}

int main()
{
    Command start("start", std::bind(start, 1, "hello world"));
    Command setRes("setRes", std::bind(setResolution, 640, 480));

    start();
    setRes();
}
于 2013-07-02T19:55:26.943 に答える