私はグローバル変数が悪いことを知り、できるだけ避けるべきです。しかし、例えばMPIを使って並列プログラムを書く場合、一部の変数は一度しか初期化されず、決して変更されません(このタスクの数、タスクの総数など)。これらの変数をグローバルなものとすることは、依然として悪い習慣と考えられていますか?これらの変数には常にアクセスする必要があるので、メインクラスのクラスを作成し、プログラム内のすべての関数の99%にポインタを渡すのは愚かなようです。これまでの私のアプローチは、mpi_globという名前空間でそれらを隠すことでした(C++の場合は、名前空間をエミュレートするためにCの構造体に入れても構わないと思います)。私は、ユニットのシステムなどの他のset-once-once変数についても疑問を抱いていると思います。グローバル変数とMPI
答えて
グローバル変数が「悪い」という理由は、識別とトレースが難しい個別のソースファイル間の結合を導入するためです。特に、プログラム内のある時点でグローバル変数が予期しない状態になった場合、変更された場所を特定するのは難しいかもしれません。
グローバル変数をプログラム内のすべての関数を参照して渡すローカル変数に置き換えても、その問題は解決されません。設計上、「トランプデータ(tramp data)」、すなわち、不要な場所でもさまよっているデータです。
ここで指摘したように、一度初期化されて変更されなかったデータには、グローバル変数を「不良」にする問題はありません。問題は存在しないため、解決策は必要ありません。
崖の上を辿るべきではなく、具体的にはあなたが書いているプログラムの種類に依存します。
あなたのプログラムが比較的小さい(またはあなたが書いている/それを書いている/保持している)人は、特別な名前空間に "グローバル"変数を残しても問題ありません。少なくともあなたは間違ってどこかでローカルスコープでそれらをシャドーしたり踏みつぶしたりすることはありません。それはあなたがこのかかわらような何かをやっていないと仮定しています:
using namespace mpi_glob;
どこかのファイルにグローバルを持つ、非常に多くのそれらを保護しないとは少し異なっています。
グローバル変数を使用してプログラムをよりわかりやすく分かりやすくするには、それらを使用します。ローカルに保管することが可能な場合は、通常は長期的にメンテナンスが簡単になるため、ローカルに保管してください。
私はSingletonがそれをより良く管理するのに役立つはずなので、ポインタを渡す必要はありません。実際には、mpi_glob
は同じですが、Singleton
はもっと慣れた方法です。
また、グローバル変数を使用することもできますが、それは悪いことではありません。あなたは1回限りの割り当てを強調したい場合、あなたは彼らにconst
を宣言し、このような静的初期化子を経由して、それらを設定することができます。
const int number_of_tasks = get_preconfigured_number_of_tasks();
あなたのグローバル変数は時定数をコンパイル保持するために使用されている場合、それらを交換することは完全に罰金ですenum
メンバーまたはプリプロセッサで定義します。そうすれば、メモリアクセスなしで即座の値をインプレースで使用することができるため、コンパイラは容易になります。
彼のコメントでシングルトンの問題を指摘してくれたことは、ピート・ベッカーになります。それらの問題があなたにも気を遣うならば、まったく異なるアプローチが取られます。
Javaプログラムの実装方法を覚えていますか?メインメソッドを持つメインクラスがあり、そのメインメソッドの中からすべてのプログラムの作業が実行されます。メインは依然としてメンバ関数です。つまり、メインクラスのいくつかのプライベートフィールドに排他的にアクセスできます(Javaの場合は静的でなければなりませんが、ここでの主な点ではありません)。
さらに、概念をCommandのような実装に拡張することができます。従来のJavaとの違いは、メインメソッドの同等性が静的ではなく、含まれるプログラムに固有の値を持つグローバル変数が非静的メンバー変数であることです。グローバル状態データにアクセスする必要があるすべての関数は、メンバ関数に変換されます。 mainメソッドもメンバ関数であるため、これは可能です。
この方法では、カプセル化とデータの安全性を高めることができます。
- 1. MPIとそのグローバル変数
- 2. 変数スコープとグローバル変数
- 3. ドットソース変数とグローバル変数
- 4. Valgrindとグローバル変数
- 5. xe:objectDataとグローバル変数
- 6. CとC++の静的グローバル変数とexternグローバル変数
- 7. ルアとメタテーブルとグローバル変数
- 8. 変数グローバル変数?
- 9. Jenkinsグローバル環境変数とノードシステム変数
- 10. javascriptのローカル変数とグローバル変数
- 11. Ocaml - グローバル変数とローカル変数
- 12. ループ内のローカル変数とグローバル変数
- 13. javascriptのローカル変数とグローバル変数
- 14. ローカル変数とグローバル変数の違い
- 15. C++のグローバル変数とローカル変数
- 16. Node.jsグローバル変数とTypeScript
- 17. Vimグローバル変数とマップリーダー
- 18. JavascriptとESLintのグローバル変数
- 19. Fortranモジュールとグローバル変数
- 20. グローバル変数と共有インスタンススウィフト
- 21. Webpack ProvidePluginとグローバル変数
- 22. グローバル変数とPythonフラスコ
- 23. サーブレットのコンテキストスコープとグローバル変数
- 24. グローバル変数とPythonは
- 25. グローバル変数と基本ブロック
- 26. ES6とウィンドウ/グローバル変数
- 27. パラメータとグローバル変数、メニュープログラム
- 28. Android - グローバル変数?
- 29. グローバル変数は
- 30. C#グローバル変数
シングルトンは定数の過剰な使用であり、グローバルデータに対して安全性の幻影を提供します。グローバルデータの問題は、任意のソースファイルから変更できるため、特定の変更が行われた場所を確認することが難しいことです。それをシングルトンにしてもそれは変わりません。シングルトンを使用することから私が認識している唯一の利点は、初期化の問題の順序を減らすことです。しかし、初期化問題の順序は、グローバルの過度の使用に起因します。グローバルの使用を減らすことで、これらの問題を軽減し、グローバルに存在するデバッグの問題を減らすこともできます。 –
@PeteBecker特に、シングルトンがゲッター/セッターのないダムオブジェクトである場合、データコントロールに関して私はあなたに同意します。この場合、シングルトンはOPが要求しなかった利点をもたらすことを意図していません。私はもっと普通の方法を表現するためにしか描かなかった。私のような一般的なプログラマが期待するだろう。それは確かに定数の過剰なものです、それは他の選択肢がある理由です。 –
シングルトンから取得するオブジェクトにゲッタとセッタがあるかどうかは関係ありません。それはまだグローバルデータです。 getterとsetterは、それほど有用ではなく、あまり単純ではありませんが、単純なグローバルデータでは役に立ちません。 –