27

1 つのクラスでのみ使用される定数文字列をいくつか定義する必要があります。次の 3 つのオプションがあるようです。

  1. 文字列を使用する場所に直接埋め込みます。

  2. それらをクラスのプライベート静的定数メンバーとして定義します。

    //A.h  
    class A {  
    private:  
       static const std::string f1;  
       static const std::string f2;  
       static const std::string f3;  
    };  
    
    //A.cpp  
    const std::string f1 = "filename1";  
    const std::string f2 = "filename2";  
    const std::string f3 = "filename3";  
    
    //strings are used in this file  
    
  3. cpp ファイルの匿名名前空間でそれらを定義します。

    //A.cpp  
    namespace {  
      const std::string f1 = "filename1";  
      const std::string f2 = "filename2";  
      const std::string f3 = "filename3";  
    }  
    
    //strings are used in this file  
    

これらのオプションを考えると、どれをお勧めしますか?またその理由は何ですか? ありがとう。

4

9 に答える 9

21

それらを CPP ファイルの匿名名前空間に配置します。それらを実装に対してプライベートにし、同時に実装の一部である非メンバー関数 ( などoperator<<) から見えるようにします。

于 2010-03-17T20:28:00.647 に答える
5

それらが単一のファイルでのみ使用される場合、それらをヘッダー ファイルに含めて外部に公開する必要はありません。

それらが使用され、常に単一の場所でのみ使用される場合、それらを使用する必要がある場所にリテラルとして記述しない理由はありません。

それらが cpp の複数の場所で使用されている場合は、匿名名前空間を使用します。

あなたが言及していない別のオプションは、それらをcpp内の静的変数として定義することです。これは匿名名前空間オプションといくらか同等で、C++ よりも C に似ています。

于 2010-03-17T20:26:24.190 に答える
3

クラスの静的メンバー。

それらが 1 つのクラスによって複数の場所で使用されている場合、それらを使用するクラスでそれらを定義したままにしておくと、通常、物事を整理しておくことが容易になり、後ですべてを定義した場所を見つけることが容易になります。それらをインプレースで定義すると、それらを見つけて後で変更することが難しくなります。また、よりクリーンなクラス定義と使用のために、匿名名前空間よりも特定のクラスを選択します。

于 2010-03-17T20:26:27.607 に答える
2

クラスの .cpp ファイルでのみ使用する場合は、名前空間を使用する必要はありません。単に次のように言います。

const std::string f1 = "filename1";  
const std::string f2 = "filename2";  
const std::string f3 = "filename3";  

名前空間の乱用は新しいことのようです。個人的には魅力がわかりません。

于 2010-03-17T20:47:44.703 に答える
2

文字列がクラスのユーザーに表示されることを意図している場合は、それらをクラスに入れます。それ以外の場合は、実装ファイルの名前のない名前空間でそれらを非表示にします。

于 2010-03-17T20:25:38.483 に答える
0

本当の問題は、クラスを実装するときに文字列が実際に内部でのみ使用されるのか、それとも他の場所で使用されるのかということです。

本当に細かいことを言うと、クラスのインターフェースをできるだけきれいに保つように努めます。そのため、ファイル名文字列が「外部」の世界にとって重要であってはなりません。.cpp ファイルのみで内部的に非表示にします。その場合、私は名前空間を気にすることはないと思いますが、物事を「静的」に保ちます (つまり、.cpp ファイルの内部)。

于 2010-03-17T20:36:58.980 に答える
0

3 つのオプションのうち、本当に避けるべき唯一のオプションは #1 です。コードでマジック Cookie を使用しないでください。定数を名前空間またはクラスに配置することで、将来のコードの拡張と保守が容易になります。

定数が本質的にグローバルである場合、2 から 3 の間ではほとんど問題になりません。重要なのは、1 つを選択し、それを維持することです。ただし、特定のクラスに適用される定数がある場合、それらはそのクラスの一部である必要があります。

個人的には、ほとんどの場合に名前空間を使用します。

于 2010-03-17T20:26:42.350 に答える
0

ただし、注意すべき点が 1 つあります。静的な std::string オブジェクトの使用はお勧めしません。代わりに、静的な char* を使用してください。この理由は、初期化の順序に関する潜在的な問題によるものです。コンストラクターが string を参照するクラスの静的インスタンスがあるとしますA::f1。まだ構築されているという保証はなくA::f1、クラッシュが発生するか、さらに悪いことに、クラッシュではなく偽のデータが発生します。

初期化の順序のバグを追跡するのは非常に厄介な場合があり、1 つのプロジェクトではすべて問題ないように見えるかもしれませんが、同じライブラリを使用して別のプロジェクトを構築すると、リンク順序の微妙な違いにより、このバグが不可解に現れることがあります。

于 2010-03-17T23:10:08.097 に答える
0

実装ファイルのファイル スコープで const 文字列を使用するだけで、その使用をそのクラスのみに制限するために匿名名前空間は必要ありません。

C++ 003 標準C.1.2 条項 3: 基本概念

Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage

注: 匿名の名前空間は、名前の競合を減らすのに役立ちます。

于 2012-10-18T16:24:10.550 に答える