ソース ファイルの先頭で部分的に定義されているインクルード ファイル (通常はそうです) と、関数内で使用されるその他のファイルに依存するコードがあります。
その典型的な例は、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() はオブジェクトを正しく初期化する必要があります。そうしないと、プログラムがクラッシュします。
私はその解決策に満足していないので、まだ質問を開いたままにしています.