質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

32118閲覧

C++ グローバル変数がクラスをまたぐと初期化される

use

総合スコア15

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2016/09/03 02:13

C++のグローバル変数がクラスをまたぐと初期化される
現象につきまして、
大変初歩的ではありますが教えていただけますと幸いです。


A.h

static int a;

class A
{
...
}


B.cpp

a=1;//aは1になる

C* C = new C(); result = C->Cmethod();

C.cpp

Cmethod
{
a;//aは0になっている
}

以上のような3つのファイルが同じプロジェクトにあるとき、
A.hにて、関数の外側で宣言されたstatic int aは、
グローバル変数として、どのクラスからでも参照でき、
全処理を通じて、値が保持されているものと個人的には
思っておりました。

しかし、B.cppでaの値を変更しても、C.cppに移ると、その変更は保持されず、
aの値は初期化されてしまっているようです。

しかしながら、a.hにおけるaの宣言を消してみると、B.cppでもC.cppでも
エラーが出ることから、B.cppでもC.cppでもA.hで宣言されたグローバル変数aを
参照しているように思われます。

この状況についての納得のいく説明がgoogle上で見つかりませんでしたので、
大変初歩的ではありますが教えていただけますと幸いです。
また、解決方法(変数を保持する方法)を教えていただけますと幸いです。

mit0223👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

A.hにて、関数の外側で宣言されたstatic int aは、

関数どころかクラスの外で定義されています。その場合、本来の意味のグローバル変数ではなく、ファイル内ローカルな変数となります。それがヘッダーに書かれているとどうなるかというと、インクルードしたソース内でのみ利用可能な変数ということになります。
したがって、A.hに書かれたstatic int a;は、B.cppとC.cppで異なる領域に確保されたまったく別の変数となり、B.cpp内で1に設定したとしても、C.cppの'a'には影響を与えません。

異なるソースで共有したい場合は、static int a;をAクラスの中にpublicアクセスで書き、A::a = 1;のように使います。

コード例

C++

1// A.h 2 3class A 4{ 5public: 6 static int a; 7 8... 9}

C++

1// A.cpp 2 3#include "A.h" 4 5int A::a;

追記

グローバル変数の正しい書き方です。ソースにグローバル変数を定義して、ヘッダーでexternを付けて宣言すると、複数のソースから同じ変数が参照できます。

C++

1// A.h 2 3extern int a; 4 5class A 6{ 7... 8}

C++

1// A.cpp 2 3int a;

投稿2016/09/03 02:45

編集2016/09/03 03:10
catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

use

2016/09/03 02:55

解答ありがとうございます。 おっしゃった通りにやってみたのですが、 その場合、A::a = 1;の部分で、 LNK200:外部シンボル""public static int A::a"(?a@staticConstDefine@@sHA)""は未解決です。 LNK112(1件の未解決の外部参照 というエラーが出てしまいます。 お手数ですが、お答え頂けますと幸いです。
catsforepaw

2016/09/03 03:02

すみません。Aクラスにstatic宣言した変数はソースのどこかに定義を書かないといけないことを忘れていました。 回答の方に追記します。
catsforepaw

2016/09/03 03:09

たびたびすみません。グローバル変数の正しい書き方を追記します(長いことグローバル変数を使うことはなかったので忘れていました)。
use

2016/09/03 03:18

迅速な解答誠にありがとうございます。 extern の方のやり方で、うまくいきました。 ちなみに、最初に教えていただいたやり方だと、訂正でコンパイルは通ったのですが、 実行時にウォッチ式の監視をすると、aの欄はなぜか、識別子"a"が定義されていません。 と出力されてしまっておりました。
catsforepaw

2016/09/03 03:31

> 実行時にウォッチ式の監視をすると、aの欄はなぜか、識別子"a"が定義されていません。 Aクラスの中に`static int a;`を書いた場合、ウォッチ式の方は`A::a`とする必要があります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問