スレッド: [cppll_novice:0791] staticなクラス内メンバについて
スレッド
- 791: 初心者な質問で恐縮なのですが c++でクラス内スタティックなメンバ変数を利用する際に たとえ hac43891
- ├799: ISO/IEC 14882-2003によると、静的記憶域期間(static storage duration) として以下の記述がありました。 NANBA Toshiaki
- │└802: Modern C++ Design なる本で シングルトンの解説があり コンパイラは、プログラムを構成する最初の hac43891‐at‐rio.odn.ne.jp
- │ └804: 異なる翻訳単位での、静的記憶域機関を持つオブジェクトの動的初期化順 序が処理系定義であ NANBA Toshiaki
- │ └805: 初期化も問題なのですが, 以前,安易に以下のようなクラスを作成したとき, アプリケーション終 Toru SHIBUYA
- └822: 失礼ではありますが、私の理解力がなく同じ質問を "C and C++ フォーラム"でもさせていただきま hac43891‐at‐rio.odn.ne.jp
[cppll_novice:0791] staticなクラス内メンバについて
- Subject:
- [cppll_novice:0791] staticなクラス内メンバについて
- From:
- hac43891 <hac43891@...>
- Date:
- Sun, 23 Jan 2005 22:58:26 +0900
- X-Mailer:
- Becky! ver. 2.12.01 [ja]
- Message-Id:
- <20050123225448.AD5D.HAC43891‐at‐rio.odn.ne.jp>
はじめましてhacと申します
初心者な質問で恐縮なのですが
c++でクラス内スタティックなメンバ変数を利用する際に
問題について質問です
たとえば
TEST_A.hpp -------------------------
class TEST_A {
public:
static SpecClass m_cSpec; // SpecClass ユーザー定義なクラス
};
-----------------------------------
TEST_A.cpp --------------------------
SpecClass TEST_A::m_cSpec;
-----------------------------------
上記のようなSpecClassというプリミティブでないような
クラスをスタティックとして利用する場合、
よくシングルトンパターンなどの説明で、他の翻訳単位
からの参照のタイミングによりそのオブジェクトの
実態がまだない場合がある、という説明をみるのですが、
このスタティックなメンバ変数にたとえばプリミティブな
変数を利用するような場合は必ず実態は保障されるのでしょうか?
つまりこの場合には安心して使えるのでしょうか?
たとえば下記のような形式です
TEST_B.hpp -------------------------
class TEST_B {
public:
static const char * const sDATA;
};
-----------------------------------
TEST_B.cpp --------------------------
const char * const TEST_B::sDATA = "testtest";
-----------------------------------
--
hac <hac43891@...>
初心者な質問で恐縮なのですが
c++でクラス内スタティックなメンバ変数を利用する際に
問題について質問です
たとえば
TEST_A.hpp -------------------------
class TEST_A {
public:
static SpecClass m_cSpec; // SpecClass ユーザー定義なクラス
};
-----------------------------------
TEST_A.cpp --------------------------
SpecClass TEST_A::m_cSpec;
-----------------------------------
上記のようなSpecClassというプリミティブでないような
クラスをスタティックとして利用する場合、
よくシングルトンパターンなどの説明で、他の翻訳単位
からの参照のタイミングによりそのオブジェクトの
実態がまだない場合がある、という説明をみるのですが、
このスタティックなメンバ変数にたとえばプリミティブな
変数を利用するような場合は必ず実態は保障されるのでしょうか?
つまりこの場合には安心して使えるのでしょうか?
たとえば下記のような形式です
TEST_B.hpp -------------------------
class TEST_B {
public:
static const char * const sDATA;
};
-----------------------------------
TEST_B.cpp --------------------------
const char * const TEST_B::sDATA = "testtest";
-----------------------------------
--
hac <hac43891@...>
[cppll_novice:0799] Re: static なクラス内メンバについて
- Subject:
- [cppll_novice:0799] Re: static なクラス内メンバについて
- From:
- NANBA Toshiaki <nanba@...>
- Date:
- Mon, 24 Jan 2005 15:44:53 +0900
- X-Mailer:
- DinosaurX Internet Mail&News v3.00.5 unicode version
- Message-Id:
- <20050124064456.3716A67C15B‐at‐ns.crest-cs.co.jp>
- In-Reply-To:
- 791
- References:
- 791
どもはじめまして、南波と申します。
On 2005/01/23 22:58:26
"[cppll_novice:0791] staticなクラス内メンバについて" hac43891 wrote:
>このスタティックなメンバ変数にたとえばプリミティブな
>変数を利用するような場合は必ず実態は保障されるのでしょうか?
>つまりこの場合には安心して使えるのでしょうか?
>たとえば下記のような形式です
>
>TEST_B.hpp -------------------------
>class TEST_B {
>public:
> static const char * const sDATA;
>};
>-----------------------------------
>
>TEST_B.cpp --------------------------
>
>const char * const TEST_B::sDATA = "testtest";
>-----------------------------------
ISO/IEC 14882-2003によると、静的記憶域期間(static storage duration)
として以下の記述がありました。
| 3.7.1 Static storage duration [basic.stc.static]
| 4 The keyword static applied to a class data member in a class
| definition gives the data member static storage duration.
ということで、まずstaticをつけたデータメンバは静的記憶域期間を持つ
ことになるようです。で、静的記憶域期間を持つオブジェクトの初期化は
こうなっていました。
| 3.6.2 Initialization of non-local objects [basic.start.init]
| 1 Objects with static storage duration (3.7.1) shall be
| zero-initialized (8.5) before any other initialization takes place.
| Zero-initialization and initialization with a constant expression
| are collectively called static initialization; all other
| initialization is dynamic initialization. Objects of POD types (3.9)
| with static storage duration initialized with constant
| expressions (5.19) shall be initialized before any dynamic
| initialization takes place.
- 静的記憶域期間を持つオブジェクトは他の全ての初期化に先立ってゼロ
初期化される
- 定数式で初期化される、静的記憶域期間をもつPOD typeのオブジェクト
は動的初期化に先立って行われる
順番としては、
静的初期化(ゼロ初期化→定数式による初期化)→動的初期化
でしょうか(定数で初期化しているものを、それに先立ってわざわざゼロ
初期化するかどうかは不明ですが)。
静的初期化されたstaticデータメンバを参照するのは、動的初期化以降の
フェーズになると思う(このあたりの実行フェーズの順序に関する記載は
見つけられなかった)ので、大丈夫…な気がします。
--
南波 利明 <nanba@...>
On 2005/01/23 22:58:26
"[cppll_novice:0791] staticなクラス内メンバについて" hac43891 wrote:
>このスタティックなメンバ変数にたとえばプリミティブな
>変数を利用するような場合は必ず実態は保障されるのでしょうか?
>つまりこの場合には安心して使えるのでしょうか?
>たとえば下記のような形式です
>
>TEST_B.hpp -------------------------
>class TEST_B {
>public:
> static const char * const sDATA;
>};
>-----------------------------------
>
>TEST_B.cpp --------------------------
>
>const char * const TEST_B::sDATA = "testtest";
>-----------------------------------
ISO/IEC 14882-2003によると、静的記憶域期間(static storage duration)
として以下の記述がありました。
| 3.7.1 Static storage duration [basic.stc.static]
| 4 The keyword static applied to a class data member in a class
| definition gives the data member static storage duration.
ということで、まずstaticをつけたデータメンバは静的記憶域期間を持つ
ことになるようです。で、静的記憶域期間を持つオブジェクトの初期化は
こうなっていました。
| 3.6.2 Initialization of non-local objects [basic.start.init]
| 1 Objects with static storage duration (3.7.1) shall be
| zero-initialized (8.5) before any other initialization takes place.
| Zero-initialization and initialization with a constant expression
| are collectively called static initialization; all other
| initialization is dynamic initialization. Objects of POD types (3.9)
| with static storage duration initialized with constant
| expressions (5.19) shall be initialized before any dynamic
| initialization takes place.
- 静的記憶域期間を持つオブジェクトは他の全ての初期化に先立ってゼロ
初期化される
- 定数式で初期化される、静的記憶域期間をもつPOD typeのオブジェクト
は動的初期化に先立って行われる
順番としては、
静的初期化(ゼロ初期化→定数式による初期化)→動的初期化
でしょうか(定数で初期化しているものを、それに先立ってわざわざゼロ
初期化するかどうかは不明ですが)。
静的初期化されたstaticデータメンバを参照するのは、動的初期化以降の
フェーズになると思う(このあたりの実行フェーズの順序に関する記載は
見つけられなかった)ので、大丈夫…な気がします。
--
南波 利明 <nanba@...>
[cppll_novice:0802] Re: static なクラス内メンバについて
- Subject:
- [cppll_novice:0802] Re: static なクラス内メンバについて
- From:
- hac43891‐at‐rio.odn.ne.jp <hac43891@...>
- Date:
- Tue, 25 Jan 2005 02:23:49 +0900 (JST)
- X-Mailer:
- FreeML Web Mailer XP; SP2
- Message-Id:
- <1153522.1106587429520‐at‐www2.local.freeml.net>
- In-Reply-To:
- 799
- References:
- 791 799
> - 静的記憶域期間を持つオブジェクトは他の全ての初期化に先立ってゼロ
> 初期化される
> - 定数式で初期化される、静的記憶域期間をもつPOD typeのオブジェクト
> は動的初期化に先立って行われる
>
> 順番としては、
>
> 静的初期化(ゼロ初期化→定数式による初期化)→動的初期化
>
> でしょうか(定数で初期化しているものを、それに先立ってわざわざゼロ
> 初期化するかどうかは不明ですが)。
>
> 静的初期化されたstaticデータメンバを参照するのは、動的初期化以降の
> フェーズになると思う(このあたりの実行フェーズの順序に関する記載は
> 見つけられなかった)ので、大丈夫…な気がします。
Modern C++ Design なる本で
シングルトンの解説があり
こんなことが書かれていました
---
コンパイラは、プログラムを構成する最初のアセンブリ言語の実行に先立って
、静的な初期化がされるよう準備します。
一方、C++は異なった翻訳単位における動的初期化オブジェクトの初期化
順序を定義していないため、大きな問題の温床を作り出しているのです
---
**
静的な初期化と動的初期化の関係がよくわからない・・・
どういうときに、どういう不幸が訪れるのだろうか・・・
サンプルみても何でかわからないし・・・(涙
> 初期化される
> - 定数式で初期化される、静的記憶域期間をもつPOD typeのオブジェクト
> は動的初期化に先立って行われる
>
> 順番としては、
>
> 静的初期化(ゼロ初期化→定数式による初期化)→動的初期化
>
> でしょうか(定数で初期化しているものを、それに先立ってわざわざゼロ
> 初期化するかどうかは不明ですが)。
>
> 静的初期化されたstaticデータメンバを参照するのは、動的初期化以降の
> フェーズになると思う(このあたりの実行フェーズの順序に関する記載は
> 見つけられなかった)ので、大丈夫…な気がします。
Modern C++ Design なる本で
シングルトンの解説があり
こんなことが書かれていました
---
コンパイラは、プログラムを構成する最初のアセンブリ言語の実行に先立って
、静的な初期化がされるよう準備します。
一方、C++は異なった翻訳単位における動的初期化オブジェクトの初期化
順序を定義していないため、大きな問題の温床を作り出しているのです
---
**
静的な初期化と動的初期化の関係がよくわからない・・・
どういうときに、どういう不幸が訪れるのだろうか・・・
サンプルみても何でかわからないし・・・(涙
[cppll_novice:0804] Re: static なクラス内メンバについて
- Subject:
- [cppll_novice:0804] Re: static なクラス内メンバについて
- From:
- NANBA Toshiaki <nanba@...>
- Date:
- Tue, 25 Jan 2005 10:54:26 +0900
- X-Mailer:
- DinosaurX Internet Mail&News v3.00.5 unicode version
- Message-Id:
- <20050125015428.2F4F467C15B‐at‐ns.crest-cs.co.jp>
- In-Reply-To:
- 802
- References:
- 791 799 802
南波です。
On 2005/01/25 02:23:49
"[cppll_novice:0802] Re: static なクラス内メンバについて" hac43891 wrote:
>静的な初期化と動的初期化の関係がよくわからない・・・
>どういうときに、どういう不幸が訪れるのだろうか・・・
>サンプルみても何でかわからないし・・・(涙
異なる翻訳単位での、静的記憶域機関を持つオブジェクトの動的初期化順
序が処理系定義であるため、以下のような場合に得られる結果がどうなる
か保証できないのが問題だと思います。
---- Global.h -----
class Global {
public:
Global() : value_(1) { }
int value_;
};
---- file1.cpp ----
#include "Global.h"
Global globalObject;
---- file2.cpp ----
#include "Global.h"
extern Global globalObject;
int globalInt = globalObject.value_;
-------------------
globalObject -> globalIntの順で初期化された場合、globalIntの値は1
になりますが、逆の順序で初期化された場合は0になります(先にゼロ初
期化が実行されるため)。
Modern C++ Designの例で言えば、運良く初期化済のSingletonオブジェク
トを使えるかもしれないし、未初期化のSingletonオブジェクトにアクセ
スしてしまうかもしれない、このどちらのケースになるのかは保証できな
い(よって保証できる他の手段を講じなければならない)、ということだ
と思います。
--
南波 利明 <nanba@...>
On 2005/01/25 02:23:49
"[cppll_novice:0802] Re: static なクラス内メンバについて" hac43891 wrote:
>静的な初期化と動的初期化の関係がよくわからない・・・
>どういうときに、どういう不幸が訪れるのだろうか・・・
>サンプルみても何でかわからないし・・・(涙
異なる翻訳単位での、静的記憶域機関を持つオブジェクトの動的初期化順
序が処理系定義であるため、以下のような場合に得られる結果がどうなる
か保証できないのが問題だと思います。
---- Global.h -----
class Global {
public:
Global() : value_(1) { }
int value_;
};
---- file1.cpp ----
#include "Global.h"
Global globalObject;
---- file2.cpp ----
#include "Global.h"
extern Global globalObject;
int globalInt = globalObject.value_;
-------------------
globalObject -> globalIntの順で初期化された場合、globalIntの値は1
になりますが、逆の順序で初期化された場合は0になります(先にゼロ初
期化が実行されるため)。
Modern C++ Designの例で言えば、運良く初期化済のSingletonオブジェク
トを使えるかもしれないし、未初期化のSingletonオブジェクトにアクセ
スしてしまうかもしれない、このどちらのケースになるのかは保証できな
い(よって保証できる他の手段を講じなければならない)、ということだ
と思います。
--
南波 利明 <nanba@...>
[cppll_novice:0805] Re: static なクラス内メンバについて
こんにちは,渋谷です.
初期化も問題なのですが,
以前,安易に以下のようなクラスを作成したとき,
アプリケーション終了間際に例外を発生させたことがあります.
template <typename T >
class BadStack {
public:
...
static T& top() { return stack_.top(); }
static void push( T const& t ) { stack_.push(t); }
...
private:
static std::stack< T > stack_;
};
アプリケーション終了間際,
いつの間にかBadStack::stack_ か解体されていて,
それに気づかずに,BadStack::stack_を
利用したstaticメソッドをコールしたために,
例外が発生したようです.
再現しようとしたのですが,
どうやって例外を発生させたのか思い出せない...
--
Toru SHIBUYA
初期化も問題なのですが,
以前,安易に以下のようなクラスを作成したとき,
アプリケーション終了間際に例外を発生させたことがあります.
template <typename T >
class BadStack {
public:
...
static T& top() { return stack_.top(); }
static void push( T const& t ) { stack_.push(t); }
...
private:
static std::stack< T > stack_;
};
アプリケーション終了間際,
いつの間にかBadStack::stack_ か解体されていて,
それに気づかずに,BadStack::stack_を
利用したstaticメソッドをコールしたために,
例外が発生したようです.
再現しようとしたのですが,
どうやって例外を発生させたのか思い出せない...
--
Toru SHIBUYA
[cppll_novice:0822] Re: staticなクラス内メンバについて
- Subject:
- [cppll_novice:0822] Re: staticなクラス内メンバについて
- From:
- hac43891‐at‐rio.odn.ne.jp <hac43891@...>
- Date:
- Wed, 2 Feb 2005 00:13:15 +0900 (JST)
- X-Mailer:
- FreeML Web Mailer XP; SP2
- Message-Id:
- <2778195.1107270795069‐at‐www3.local.freeml.net>
- In-Reply-To:
- 791
- References:
- 791
hacと申します
失礼ではありますが、私の理解力がなく同じ質問を
"C and C++ フォーラム"でもさせていただきました。
その結果、ようやく理解することができました。。
みなさん、どうもありがとうございました。
失礼ではありますが、私の理解力がなく同じ質問を
"C and C++ フォーラム"でもさせていただきました。
その結果、ようやく理解することができました。。
みなさん、どうもありがとうございました。