2016-10-07 6 views
5

私のコードは非常に大きいですが、私はできるだけ最善を尽くすようにここで最小化しようとします。グローバルに定義されている静的変数がリセットされるのはなぜですか?

基本的に私は1つの場所(私のメイン)で変更された文字列を定義して、私のプログラム全体で読み上げたいと思っています。

私のdefine.hはどこにも含まれていますので、そこに定義しました。私は私の主な機能には

static std::string MAINLOG = "RANDOMNES"; 

for (int i = 0; i < files.size(); i++){ 

    // Do stuff  

    prepDbugDir(); // This sets MAINLOG to "CORRECT_VALUE" 

    std::cout << "Before " << MAINLOG << std::endl; 

    // Call a class function whose includes include my defines.h 

    std::cout << "After " << MAINLOG << std::endl; 


} 

そして、私のファイルの印刷が

Before CORRECT_VALUE 
RANDOMNESS 
After CORRECT_VALUE 

だから私の質問は、なぜ、どのようにされている私は価値があることを得ることができます私のクラスの中で維持されます。

+0

複数の* .aまたは* .oプログラム情報を分割しましたか?それはいくつかのオブジェクトファイルにあなたの分割のプログラミングのために、MAINLOGのいくつかのコピーが存在するようです。 –

+0

コンパイルすると、はい。それが問題ならば、これを回避する方法がありますか? – aarelovich

+1

MAINLOGの宣言をヘッダーに入れ、ヘッダ(おそらくdefine.cpp)を含む単一の.cppファイルに1回だけ定義を入れてみてください。 – Baldrick

答えて

6

defines.hを含むすべての翻訳単位(基本的に.cまたは.cppファイル)には、変数のコピーがあります。

私は、ヘッダーに

extern std::string MAINLOG; 

をグローバルexternを宣言してから.Cファイルまたは.cppファイル

std::string MAINLOG = "RANDOMNES"; 
のいずれかで非静的グローバル変数として定義すると考えています

が問題を解決します。しかし、それは貧弱なコーディングスタイル、IMOです。 C++の方法は、少なくともシングルトンクラスになります。

私は、コンテキストを知らなくても、意味のある名前を付けることはできませんが、以下のような考え方は次のとおりです。

mainlog.h

class Mainlog { 
    Mainlog() = default; // Private default constructor 

    static Mainlog& instance(); 

public: 
    static const std::string& get() { 
     return instance().value; 
    } 

    static void set(const std::string& newValue) { 
     instance().value = newValue; 
    } 

private: 
    std::string value {"RANDOMNESS"}; 
}; 

mainlog.cpp(ヘッダにこれを入れないでください! )

Mainlog& Mainlog::instance() { 
     static Mainlog mainlog; 
     return mainlog; 
    } 
+1

シングルトンクラスがグローバル静的属性よりも優れていることに同意します –

+0

私はmain.cppを持っています。私は私のmain.cpp内の私のメインと外部のメインログを宣言し、私はそれを値に設定しました。私がこれを行うと、私は実際にそれを読んでいる 'MAINLOG 'への未定義の参照、リンカエラーを取得します。 – aarelovich

+1

シングルトンクラスの例を教えてもらえますか? – aarelovich

3

これは私がお勧めするものです。 defines.hで

:main.cppには

const std::string& mainlog(); 

const std::string& mainlog() { 
    static std::string MAINLOG = "CORRECT_VALUE"; 
    return MAINLOG; 
} 
+0

実行中に値が複数回変更されるため、constは使用できません。 – aarelovich

+0

しかし、メインでそれを変更したいと思います。他の誰かがそれを変更できないようにするため、const参照を参照することはできますが、変更はできません。これも最初に公開されたシングルトンでした。しかし、MAINLOG(単にstd :: string)のコピーを返すこともできます –

1

あなたは、あなたの.CPPファイルに含めるあなたのdefines.hファイルにそれを置くので、各.cppファイルは文字列の独自のインスタンスを取得し、その.cppファイル内でのみ表示されます。 staticは、宣言されている.cpp内の変数のみを表示します。

変更するには、このように、あなたのdefines.h内でexternする静的:1とあなたの唯一の1で次に

extern std::string MAINLOG;

。cppファイルの場合は、次のように追加します。

std :: string MAINLOG = "RANDOMNES";

これはあなたの期待する動作を提供しますが、このようなグローバル変数は悪い考えです。

+0

ヘッダファイルのエントリにイニシャライザを付ける必要はありません。 –

+0

それは正しいです。私はそれを修正します。 (カットアンドペーストの喜び) –

0

静的記憶域を持つ変数をヘッダーに定義すると、各変換はその名前で独自の一意の変数を取得します。

簡単な修正、あなたがシングルトンの道を行くしたくない場合は、あなたのヘッダーで

extern const std::string& MAINLOG; 

を宣言することで、その後、メインファイルには、これが与える

std::string MAINLOG_INTERNAL = "RANDOMNESS"; 
const std::string& MAINLOG = MAINLOG_INTERNAL; 

を定義しますプログラムの残りの部分に読み取り専用の "ビュー"を持つ書き込み可能な文字列を返します。メインファイルに

その後することができます

void prepDbugDir() 
{ 
    MAINLOG_INTERNAL = "CORRECTNESS"; 
} 

関連する問題