16

プライベートな静的データ メンバーを持つクラスが時々あります。これらを実装ファイルの名前のない名前空間の静的変数に置き換える必要があるかどうか、現在議論しています。これらの変数をインライン メソッドで使用できないこと以外に、他に欠点はありますか? 私が見る利点は、クラスのユーザーからそれらを完全に隠すことです。

4

6 に答える 6

4

読みやすさの影響に見合うだけのメリットがあるとは思えません。私は通常、プライベートなものは「十分に隠されている」と考えています。

于 2009-05-13T13:17:18.113 に答える
4

1) バイナリ構成に追加の制限という形で欠点があります。1990 年代の C++ カンファレンスでのプレゼンテーションで、Walter Bright は、相互に呼び出す関数が同じコンパイル ユニット内にあるようにコードを整理することで、大幅なパフォーマンスの向上を達成したと報告しました。たとえば、実行中に Class1::method1 が他の Class1::method よりもはるかに多くの Class2 メソッドを呼び出した場合、class2.cpp で Class1::method1 を定義することは、Class1::method1 がメソッドと同じコード ページにあることを意味します。呼び出し中だったので、ページ フォールトによって遅延する可能性が低くなりました。この種のリファクタリングは、ファイルの静的よりもクラスの静的を使用する方が簡単です。

2) 名前空間キーワードの導入に反対する議論の 1 つは、「クラスでも同じことができる」というものでした。名前空間以前の時代のソースでは、class と struct が貧弱な名前空間として使用されていることがわかります。説得力のある反論は、名前空間は再度開くことができ、任意の関数が名前空間の一部になったり、外部の名前空間にアクセスしたりできるため、クラスでは実行できない名前空間で実行できることがあったためです。これは、言語委員会が名前空間のスコープをクラスのスコープと非常によく似ていると考えていたことを示唆しているため、あなたの質問に関係しています。これにより、静的なクラスの代わりに匿名の名前空間を使用する際に、微妙な言語上の罠が発生する可能性が減少します。

于 2009-05-13T13:27:44.510 に答える
2

私は他の答えに同意しません。できるだけクラス定義から外してください。

Scott Meyers の『Effective C++ 3rd edition』では、クラス メソッドよりも非フレンド関数を優先することを推奨しています。このようにして、クラス定義は可能な限り小さくなり、プライベート データは可能な限り少ない場所でアクセスされます (カプセル化されます)。

この原則に従うと、さらにpimpl イディオムにつながります。ただし、バランスは必要です。コードが保守可能であることを確認してください。盲目的に、このルールに従うと、すべてのプライベート メソッド ファイルをローカルにし、必要なメンバーをパラメーターとして渡すだけになります。これにより、カプセル化が改善されますが、保守性が損なわれます。

とは言っても、ファイル ローカル オブジェクトの単体テストは非常に困難です。いくつかの巧妙なハッキングにより、単体テスト中にプライベート メンバーにアクセスできます。ファイル ローカル オブジェクトへのアクセスは、もう少し複雑です。

于 2009-05-14T02:12:30.343 に答える
1

要するに、これらの変数がクラスのコンテキストで実際の意味を持っているか (たとえば、すべてのオブジェクトで使用される共通メモリへのポインター)、またはメソッド間で受け渡しする必要があり、むしろ混乱したくない一時データがあるかどうかにかかっていると思います。とのクラス。後者の場合、名前のない名前空間を使用することは間違いありません。前者の場合は、個人の好みの問題だと思います。

于 2009-05-13T13:28:54.617 に答える
1

名前のない名前空間のメンバーはプライベート データと同じようにカプセル化されていないという点で、私は Greg に部分的に同意します。結局のところ、カプセル化のポイントは、他のプログラマーからではなく、他のモジュールから実装の詳細を隠すことです。とはいえ、これが有用なテクニックである場合もあると思います。

次のようなクラスを考えてみましょう。

class Foo {
public:
    ...
private:
    static Bar helper;
};

この場合、Foo を使用したいモジュールは、Bar の定義を知っている必要がありますが、その定義はまったく関係ありません。このようなヘッダーの依存関係は、再構築の頻度と時間の増加につながります。ヘルパーの定義を Foo.cpp の名前のない名前空間に移動することは、その依存関係を解消する優れた方法です。

また、名前のない名前空間は、静的データ メンバーよりも読み取りや保守が困難であるという考えにも強く同意しません。ヘッダーから無関係な情報を取り除いても、ヘッダーはより簡潔になります。

于 2010-06-26T01:16:16.453 に答える
1

クラスのユーザーからそれらを隠すだけでなく、あなたからも隠します! これらの変数がクラスの一部である場合、何らかの方法でクラスに関連付ける必要があります。

それらをどうするかによって、静的メンバー関数内でそれらを静的変数にすることを検討できます。

// header file
class A {
  public:
     static void func();
};


// cpp file
void A :: func() {
    static int avar = 0;
    // do something with avar
}
于 2009-05-13T13:19:51.510 に答える