5

グローバル変数を機能させるのに小さな問題があります。Visual Studio 2008 と標準の C++ を使用しています。

私は 2 つのプロジェクトを持っています。1 つは静的ライブラリで、もう 1 つはこのライブラリを使用するテスト プログラムです。global.h にグローバル変数があります

#ifndef GLOBAL_H
#define GLOBAL_H

#include <string>

extern std::string globalWord;

#endif // GLOBAL_H!

この変数を初期化する global.cpp があります。この変数は、ライブラリ プロジェクト内で使用されます。テスト プロジェクトからこの変数に値を設定していますが、その値がライブラリ プロジェクトに反映されていません。

デバッグしたところ、テスト プロジェクトに新しい値が表示されましたが、コントロールがライブラリ プロジェクトに到達すると、この変数の値は空と表示されます。このグローバル変数のスコープは、それが属するプロジェクトにのみ限定されていますか?

または、これを行うより良い方法はありますか?この値を渡すために、ライブラリ内の関数またはコンストラクターのパラメーターを変更したくありません。

どんな助けでも素晴らしいでしょう。

編集:

この変数が global.cpp でどのように宣言されているかを次に示します。

#include <string>
#include "../global.h"

std::string globalWord = "";

これは私のライブラリでそれを使用した方法です

#include "../global.h"
string text = globalWord;

ありがとう

4

4 に答える 4

8

グローバル変数を使用しないでください。ただしないでください。グローバルにアクセス可能なデータが必要な場合は、次のように globalWord を返すグローバル関数を使用することをお勧めします。

std::string globalWord()
{
    static std::string word("Hi Mom");
    return word;
}

これにより、初期化順序の問題を回避できます (Effective C++ 項目 #4 を参照)。

于 2009-02-13T02:13:22.207 に答える
6

「extern」キーワードを使用すると、実際の変数が別の場所に存在することをコンパイラーに伝えます。また、extern を除いた同じ名前の変数を1 か所だけ作成する必要があります。通常、2 つ定義するとリンカからエラーが発生しますが、1 つがライブラリにあり、1 つがライブラリにない場合、リンカはそれを理解できない可能性があります。

編集: global.cpp が両方ではなく、ライブラリまたはテスト プログラムのみにあることを確認してください。

于 2009-02-13T02:11:17.580 に答える
3

問題は、初期化順序の 1 つである可能性があります。globalWordプログラムがリンクされると、初期化で使用される場所が 2 つあります。

  1. text( "string text = globalWord;")の初期化中
  2. globalWord自分自身の初期化

残念ながら、C++ 標準は、異なるモジュールからのグローバルの初期化の順序を指定していません。関数または単純なクラス (たとえば、シングルトン) を使用してグローバル値にアクセスするというMatt の回答に似たものは、特定の初期化順序を強制する通常の方法です。

C++ FAQ では、これについて少し説明しています。プログラムで変更を計画してglobalWordいる場合、「初回使用時の構築」関数の背後に隠されている値の設定に対処していないように見えるため、状況は彼らが議論するよりも少し複雑になります。 . 通常、そのようなものには singleton class のようなものが必要です。

于 2009-02-13T02:27:36.650 に答える
2

あなたが記述した種類の動作は、DLL がある場合に問題のように思えますが、ライブラリが静的であると言っているのは奇妙に見えます。

とにかく、複数のライブラリのグローバル変数には注意してください。共有コード ライブラリ (DLL) がある場合は、各部分の値を取得します。この質問をチェックしてください。役に立つ場合があります。

于 2009-02-13T02:32:25.360 に答える