3

文字列 const を宣言する方法として、どちらがより推奨されますか?

  1. ファイルスコープでグローバル変数を宣言することです。
  2. クラスに対してグローバルに宣言します。

変数は、クラス メンバー関数でのみ使用されます。クラスメンバー関数のみに固有であるため、2の方が優れていると感じる傾向があります。

A.cpp
---------------------
static const std::string hello_str = "Hello";

void A::print()
{
    std::cout << hello_str;
}

(また)

A.h
---------------------
class A{
public:
    static const std::string hello_str;
    void print();
}

A.cpp
---------------------
const std::string A::hello_str = "Hello";

void A::print()
{
    std::cout << A::hello_str;
}

編集-1:

hello_str の内容は変更される可能性があります。例えば。文字列は、開発者がファイルを変更するたびに手動で更新されます。

この場合、変数の初期化を関数内に保持することは理にかなっていますか? ユーザーが文字列を更新することは、明確または明白ではない場合があります。ファイル(1)またはクラス(2)に対してグローバルに保持されている場合、他の開発者はこの文字列を「識別」および変更できます。

上記の使用例を考慮して、文字列を返す関数を使用することをお勧めしますか? または、クラス レベルの静的変数 (プライベート アクセス指定子を使用) を使用できますか?

4

2 に答える 2

4

匿名の名前空間は別のオプションです:

A.cpp

namespace {
  const std::string hello_str("Hello");
}

void A::print() {
    std::cout << hello_str;
}

しかし、遅延初期化のためにそれを関数にラップする必要があります。

これは次の形式になります。

A.h
---------------------
class A{
public:
    static const std::string& hello_str();
    void print();
}

A.cpp
---------------------
const std::string& A::hello_str() {
  static const std::string str("Hello"); // << constructed on first call of A::hello_str()
  return str;
}

void A::print() {
    std::cout << A::hello_str();
}

この場合、単純に値で戻り、静的/グローバルを完全に回避することもできます。標準 C++ ライブラリの実装では、「小さな文字列の最適化」と呼ばれるものを使用する場合があります。その場合、この短い文字列を作成または移動するためにヒープ割り当ては必要ありません。

また、2 つの例は同じではないことに注意してください。1 つは事実上非公開で、もう 1 つは公開されています。

最終的には、提案したどちらのアプローチも使用しないでください。遅延初期化、または (多くの場合はさらに良い) 値による戻りのために、関数内の static を検討してください。

元の質問に答えるには、クラス内での宣言を好みますが、プライベートです。これは、実装が変化するイベントで維持するのが簡単だと思います。そしてもちろん、cpp のその static が何らかの形で外部の実装にアクセスできる場合は、クラス内でそれをプライベートとして宣言して、他の人がアクセスできないようにすることもできます。

于 2012-08-30T04:56:22.777 に答える
2

簡単なルール:

  • string論理的にクラスに属しているため、クラス メンバーである必要があります。
  • クラスのすべてのインスタンスは同じ文字列を共有するため、クラスに属し、クラスの特定のインスタンスではありません(すべてのインスタンスが同じ文字列を共有します)ので、staticメンバーにします。

これにより、次の利点が得られます。

  • グローバル文字列として宣言する場合とは異なり、文字列にアクセスする必要があるクラス メンバーのみがアクセスできます。
于 2012-08-30T04:53:58.360 に答える