1

ソース ファイルの先頭で部分的に定義されているインクルード ファイル (通常はそうです) と、関数内で使用されるその他のファイルに依存するコードがあります。

その典型的な例は、OpenFOAM ソルバーのソースです。

このコードのスキームは非常に手続き的なものですが、これらすべてを init()、run()、およびおそらく release() を提供するクラスに入れたいので、いくつかの変数をプライベートとしてクラスに入れる予定です。メンバー。

含まれているファイルはライブラリに属しているため、変更したくありません。

クラスを使用する理由は、他のルーチン クラスがこのコードと一緒に実行されるためです。

これが事です。init() はいくつかの変数を準備する必要があり、明示的なコンストラクターや特別な引数ではなく、これらの変数 (他のクラスの型である) が存在する状況があります。一度呼び出されます。run() が数回呼び出されます。手続き型コードにはループのみがあり、そのループの内容は run() メソッドに入れられます。

したがって、最善の解決策は、これらの変数を std::unique_ptr に配置することであり、init は必要なものを構築できます。明らかにそのトリックで変数の署名が変更されたので、次のような参照の 2 番目の宣言を作成しました。

    std::unique_ptr<volScalarField> mp_p;
    volScalarField &p = *mp_p;

ちょっと面倒なのでマクロを作ってみました

    FOAMPTR(volVectorField, p)

これは私のためにすべての作業を行います:

    #define FOAMPTR(TYPE,NAME) std::unique_ptr<TYPE> mp_##NAME; TYPE &NAME=*mp_##NAME

それはかなりうまく機能しますが、特にコードをデバッグする必要がある場合は、一般的にマクロのファンではありません。

今私の質問は次のとおりです。これに取り組み、すべての魔法を行う可能性のあるテンプレート定義のようなものを使用するより良い方法はありますか?

編集:「かなりうまくいく」とは、コンパイラがそれを翻訳できることを意味します。ただし、参照はまだ無効です。

編集:わかりました、2つのマクロを使用して無効なポインターの問題を解決しました:

    #define FOAMPTR(TYPE,NAME) std::unique_ptr<TYPE> mp_##NAME
    #define FETCHFOAMREF(NAME) auto &NAME=*mp_##NAME

今、私FOAMPTR(TYPE,NAME)はメンバーに置くと、私は自分のユニークなptrsを取得します. このrun()メソッドでは、2 番目のマクロFETCHFOAMREF(NAME)が使用されます。もちろん、init() はオブジェクトを正しく初期化する必要があります。そうしないと、プログラムがクラッシュします。

私はその解決策に満足していないので、まだ質問を開いたままにしています.

4

0 に答える 0