2

Visual C ++2010Expressコンソールアプリケーションに取り組んでいます。

詳細に入る前に、ここでの要約は次のとおりです。関数の配列/リスト/ベクトルを作成し、その配列からそれらを呼び出すにはどうすればよいですか?

そのため、関数ポインタに少し問題があります。'Terminal'クラスを作成しています。このクラスには、メンバークラス'CommandMap'があります。CommandMapクラスの目的は、関数のベクトル/配列とそれらを表す文字列を別のベクトル/配列に格納することです。クラスがベクターから関数を呼び出すときにのみ関数が呼び出されるようにしたいのですが、関数をベクターに追加したときにのみ実行され、呼び出そうとしたときは実行されませんでした。

タイプを定義してみました:

typedef void (*CmdCallback)();

それらを含むベクトルを宣言しました:

vector<string> CmdNames;
vector<CmdCallback> CmdFuncs;

私はそれらを次のように追加します:

// Map a new command
bool CommandMap::Map(string name, CmdCallback func)
{
    if (!IsNullOrSpace(name) && func != NULL)
    {
        if (!Exists(name))
        {
            CmdNames.push_back(name);
            CmdFuncs.push_back(func);
            return true;
        }
    }

    return false;
}

そして、私はそれらを次のように呼んでみます:

// Get a command callback from its identifier
CmdCallback CommandMap::GetFunc(string name)
{
    int index = IndexOf(name);
    if (index == -1) return NULL;
    else return CmdFuncs.at(index);
}

// If the given string is a command indentifier
// it will invoke the associated callback.
bool CommandMap::Exec(string input)
{
    for each (string id in CmdStrings)
    {
        if (input == id)
        {
            CmdCallback cmd;
            cmd = GetFunc(id);
            cmd();
            return true;
        }
    }

    return false;
}

私はこれを使ってみました:

CmdCallback SayHello()
{
    cout << "Hello World!" << endl;
    return NULL; // Forces me to return null, guessing since it's
                 // not 'void' but a 'void' pointer it must return something
}

int main(int argc, char *argv[])
{
    App = new Terminal(argc, argv);
    App->Commands->Map("say", SayHello);

    while (!App->ExecComplete)
    {
        App->WaitEnter();
        App->Commands->Exec("say");
        App->WaitEnter();
        App->ExecComplete = true;
    }

    return App->ExitCode;   
}

これは最初は機能します。ただし、関数を実行しようとすると、関数が呼び出されMap()ます。そして、私がExec()「言う」と、コールバックを見つけますが、それを呼び出そうとすると、このランタイムエラーが発生します。これには、中断または続行するオプション以外の詳細は表示されません。それが私に与えるコードはです。

私は自分のメソッドを放棄して新しいアプローチを試したいと思っています。おそらく、voidポインターtypedefで間違った方向に進んでいるので、「&」または「*」を好きではない場所にスローする必要があります。Map()引数リスト。たぶん、ベクトルもこれを行うための最良の方法ではありません。

基本的に、配列からそれらを参照することによって呼び出すことができる(そして唯一の)関数の配列を作成するにはどうすればよいかを尋ねています。私はコールバックでひどいです。

4

2 に答える 2

3

std :: 関数を使用できます。または、C ++ 11をサポートしていない場合は、boost::functionを使用できます。これらは、フリー関数またはメンバー関数から簡単に構築できる関数オブジェクトラッパーです。これらは、標準ライブラリコンテナまたは単純な配列に格納できます。

于 2012-09-02T08:41:02.180 に答える
2

私が正しく理解していれば、実際には as へのポインターが関数のベクトルに必要な型 (つまり ) を持つように宣言SayHelloするvoid SayHello()必要がありSayHelloますvoid (*)()CmdCallback

于 2012-09-02T08:45:48.153 に答える