0

ドキュメントを解析し、派生クラスを呼び出して、ストリームで見つかった特定のイベントを通知するクラスがあります。パーサーはエンコーディングを処理し、ドキュメントの一部を文字列に再書き込みする必要があるため、仮想メソッドがオーバーライドされていない場合は再書き込みを避けたいと思います。疑似コード:

class Parser
{
    virtual void Callback ( string )
    {
        // Do nothing
    }
private:
    void ParseFile()
    {
        // Parse the file in the files encoding
        // Checks and more checks
        // Found sth. So need to convert to a string a call the
        // callback, but if there is no callback what's the point
        // in wasting cycles?

        if ( Callback ) // In the world of C we could check for a func pointer
            Callback( /* with the string */ )
    }
}
class User : public Parser
{
    void Callback ( string )
    {
        // This string means sth. me
    }
}
class NonUser : public Parser
{
    // I don't care about Callback so I won't implement it
}

C コードでは、関数を作成し、その関数へのポインターを実装に渡します。内部的には、ポインターが何かを指しているかどうかを確認して呼び出します。派生クラスで同じことをどのように実装できますか? すなわち。仮想メソッドが実際に派生クラスに存在するかどうかを確認してから、時間/CPU サイクル/メモリを浪費して不要な文字列を作成します。

移植可能であれば、コンパイル時のチェックが理想的ですが、これはvテーブルと関係があると考えているため、実行時のチェックも機能する可能性があります。

さらに調査を重ねた結果、v-table が存在しないことが明らかになりました。これはほぼ不可能です。質問を少し変更して、何らかのタイプの、おそらくテンプレート、トリックを使用して上記が可能ですか?

4

1 に答える 1

0

パラメータを astd::futureにして、単純な派生アプローチを使用できます。

または、文字列の代わりに、それを提供できるプロキシまたは関数を渡します。

または、テーブルをひっくり返して、何も渡さず、作成された文字列を返すメンバー関数を Base に配置します。

もう 1 つのアプローチは、機能に仮想述語関数を持たせることです。基本クラスでは false を返し、他のクラスでは true を返すので、実際の作業を行う前にそれを呼び出すことができます。または、静的関数で実行できる可能性が高い場合は、実装の関数へのポインターを返すこともできます。(そして、これは別のパラメーターとして渡すことができます...)

vtables を結論付ける研究を読むのは興味深いでしょう。

テンプレートは、コンパイル時にターゲットに伝えることができる場合にのみ役立ちます。あなたが述べた問題は、実行時にのみ表示される情報を処理することを意味します。そして、それには、実際に渡されるいくつかのポインターまたはその他の情報が必要です。しかし、問題の洗練された説明を思いつくかもしれません。

于 2013-06-16T09:55:29.700 に答える