Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
スモモ

Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#1

投稿記事 by スモモ » 13年前

皆様、お久しぶりです。
スモモです。
お世話になっております。
新しくなってから、今日は初めてです。

さっそく 、お聞きしたい事あります。

Global変数とStaticGlobal変数とClassStaticデータメンバの違い
を教えてほしいです。

スモモ

Re: Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#2

投稿記事 by スモモ » 13年前

追加です。

//111111111111111111111111111111111111
//xxx.h
class a
{
a();
....
};
//xxx.cpp
int b = 0;
a::a(){b++;}
//222222222222222222222222222222222222
//xxx.h
class a
{
a();
....
};
//xxx.cpp
static int b = 0;
a::a(){b++;}
//333333333333333333333333333333333333
//xxx.h
class a
{
static int b;
a();
....
};
//xxx.cpp
int a::b = 0;
a::a(){b++;}


1と2と3の違い。
ご教授の程、よろしくお願いします。

dic
記事: 657
登録日時: 13年前
住所: 宮崎県
連絡を取る:

Re: Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#3

投稿記事 by dic » 13年前

1と2の違い
xxx.cppで static をつけない int b を宣言、定義、使用してますが
たとえば xxxy.cpp ファイルを追加したときに効果がでてきます

xxx.cpp で
int b = 0;
xxxy.cpp で
int b = 0;
とすると2回以上定義されコンパイルエラーになります

なので
xxx.cpp で
static int b = 0;
xxxy.cpp で
static int b = 0;
とすれば、それぞれのファイルでユニークな int b が作られます




2と3の違い

2がstatic int b で xxx.cpp ファイル内で有効で
3がclass a::b で有効です
たとえば

コード:

class a
{
 static int b;
 public:
  a() { }
  a( int v ) { b = v; }
  void f() { cout << b << endl; }
};
int a::b;

void main()
{
  a  hoge( 10 );
  hoge.f();
  a  hoge2;
  hoge2.f();
}
としたら hoge::b と hoge2::b の値は同じく10になります
なかなか違いがわかる例がわかりづらいかもしれないですが
私からの説明はこうなります

スモモ

Re: Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#4

投稿記事 by スモモ » 13年前

dic 様

まだわかりませんが。

教えていただき、ありがとうございます。

アバター
lriki
記事: 88
登録日時: 13年前

Re: Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#5

投稿記事 by lriki » 13年前

dicさんの説明を受けて、どこまでわからないのか書いていただけると有りがたいのですけど・・・(全然わからない! 1と2の違いまでは・・・ッ! etc)
とりあえず2と3に関して、例えばどんなふうに使えるのかということでアドバイスさせていただきますね。



2について・・・

例えばオープンソースのモジュールを(または他の人と共同で開発する時など)
自分のプロジェクトに組み込んでコンパイルする必要があるときに出てくる問題への対処に使います。

自分は b というグローバル変数を使いたけど、もしかしたら組み込んだモジュールの中で、
同じ名前のグローバル変数が定義されているかもしれません。
その場合は dic さんのおっしゃっているように、コンパイルエラーが出ます。
そんな不具合を避けるために、モジュール作成者が
「このグローバル変数は私が書いたソースの中だけで参照しますよ」って意味で static をつけます。



3について…

色々端折って言うと、「class a のインスタンスだけが参照できるグローバル変数」というイメージです。

例えば、class a のコンストラクタで b をインクリメント(スモモさんの貼っていただいた例ですね)し、
デストラクタでデクリメントすればclass a のインスタンスがいくつ作成されているかを知ることができます。

これを利用すれば new を使ってインスタンスの作成を行っている場合、
プログラム終了時に b の値をチェックすることで delete 忘れが無いかどうかチェックすることもできます。
(実際に全部のクラスに実装するのは大変ですけど…)


私は普段はシングルトンクラスの実装くらいにしか使いませんけど、よろしければ参考にしてみてください。

スモモ

Re: Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#6

投稿記事 by スモモ » 13年前

梨樹 様

教えていただき、ありがとうございます。

1と2、1と3の違いわかりました。

2と3の違いもちょっと教えていただければ、うれしいです。

//222222222222222222222222222222222222
//xxx.h
class a
{
a();
....
};
//xxx.cpp
static int b = 0;
a::a(){b++;}
//333333333333333333333333333333333333
//xxx.h
class a
{
static int b;
a();
....
};
//xxx.cpp
int a::b = 0;
a::a(){b++;}

2の StaticGlobal変数 3の ClassStaticデータメンバ 
はクラス内しか使わないなら、同じでしょうか?

ご教授の程、よろしくお願いします。

アバター
lriki
記事: 88
登録日時: 13年前

Re: Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#7

投稿記事 by lriki » 13年前

例えば「b は絶対にクラス a のメンバからのみアクセスしたい」というときのアクセス制限のために使い分けます。

2の場合、xxx.cpp にクラス a 以外の関数の定義を書いていたときは
その関数からもアクセスできてしまいます。

コード:

//xxx.h
class a
{
	a();
	....
};

void add();

コード:

//xxx.cpp
static int b = 0;
a::a(){b++;}

void add(){b++;}	// class a のメンバ関数じゃないけどアクセス可能!
逆に3の場合は b を private で宣言している限り、クラス a のメンバからしかアクセスできません。


簡単ですがまとめると、

「同じソースコードの中だけでアクセスします!」というときは 2。
「クラスの中だけでアクセスします!」というときは 3。

・・・といったイメージで使い分けます。


スモモさんが個人で開発をしていて、「クラス内しか使わない」というルールを守っていれば
どちらでも大差はないと思いますが、それ以外の場合(共同開発や、他の人にレビューしてもらう等)は
アクセス範囲の制限は守っておいた方がいいと思います。

スモモ

Re: Global変数とStaticGlobal変数ClassStaticデータメンバの違いについて

#8

投稿記事 by スモモ » 13年前

梨樹 様

教えていただき、ありがとうございます。

解決です。

dic 様、梨樹 様

お二人のおかげで、1つの問題ではなくほか問題にもわかるようになりました。本当にありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る