C++/STLの動作についての質問

このQ&Aのポイント
  • クラスのインスタンス化時に自身のポインタをストックしようとしたが、出力が0となり、予想に反していた。
  • "test.cpp"の3行目を"main.cpp"に移動すると正しく動作する。
  • これはどういった動作が原因で起こったのか疑問である。
回答を見る
  • ベストアンサー

C++/STLの動作

お世話になっております。 クラスのインスタンス化時に自身のポインタをストックしようと下記を実行しましたが、 出力が0となり、予想に反していました。 そこで、"test.cpp"の3行目を"main.cpp"に移動すると正しく動作します。 これはどういった動作が原因で起こったのでしょうか? よろしくお願いします。 /// test.h /// #include <vector> class Test { public: Test(){list.push_back(this);} static std::vector<Test*> list; }; /// test.cpp /// #include "test.h" std::vector<Test*> Test::list; /// main.cpp /// #include <stdio.h> #include "test.h" Test test; void main() { printf( "%d\n", test.list.size() ); // "1"と出力されると思ったけど… }

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

異なる翻訳単位で定義された非局所オブジェクトの初期化順序は不定だからです。 これを、main.cppで std::vector<Test*> Test::list; Test test; のようにすると、同じ翻訳単位になるわけですから、その初期化順序は書いた順番になります。

ClickHere
質問者

お礼

ご回答ありがとうございます。 お礼が遅くなってしまいました。 >同じ翻訳単位になるわけですから、その初期化順序は書いた順番になります。 やはり、コンパイラ依存の動作なんですね。 勉強になりました。

関連するQ&A

  • C++ STL vectorの使い方

    こんばんは。 C++のstd::vectorに関する質問です。 vectorをポインタ渡しにしたときに メンバにアクセスする方法を知りたいのですが・・・ 以下ソースの☆の部分をどう記述したらよいでしょう? #include <vector> typedef struct test {  char name[10];  char id[2]; } TEST; void funcVectorTest( std::vector<TEST> *a); int main(){  std::vector<TEST> a;  int i;  TEST foo= {"Taro","0"};  a.push_back(foo);  printf("%s",a[0].name);  a.push_back(foo);  printf("%s",a[1].name);  funcVectorTest(&a);//vectorのアドレス渡しテスト  printf("%s", a[2].name);//vectorのアドレス渡し確認  return 0; } void funcVectorTest( std::vector<TEST> *a) {  int i;  int cnt;  TEST *b;  b = new TEST[3];  TEST foo= {"Taro","0"};  a->push_back(foo);  cnt = a->size();  for( i = 0; i < cnt;i++){  //以下でa[i]のnameにアクセスしたいのですがうまくいっていません。  //☆strcpy( b[i].name, a[i]->name );  }  delete[] b; } お分かりになる方、お知恵をお貸し下さい(><) vectorについて最近知ったばかりでいまいち使い方が 分かっていない部分があるので このやり方がまずいということであれば教えていただけると 助かります。 よろしくお願いしますm( _ _ )m

  • C++ 多態とstlのコンテナについて

    以下のように、継承関係を作ります。 --------------------------------------- #include <iostream> #include <list> #include <vector> using namespace std; struct Base { virtual ~Base() = 0; }; Base::~Base() {} struct Sub1 : Base { int v; Sub1(int i) { v = i; } }; struct Sub2 : Base { double v; Sub2(double d) { v = d; } }; --------------------------------------- この場合、 Sub1, Sub2 のインスタンスをなにかコンテナに入れたい場合は、一般的には以下のように書けばいいのでしょうか? ---------------------- list<Base*> l; vector<Base*> v; Sub1 s1(3); Sub2 s2(4.4); l.push_back(&s1); l.push_back(&s2); v.push_back(&s1); v.push_back(&s2); ---------------------- list<Base>, vector<Base>も試しましたが list<Base> は宣言したところで vector<Base> は push_back() したところで コンパイルエラーになりました。 これは、こういうものなのでしょうか? むしろ、struct(もしくはclass)の書き方を変えたりすれば、問題なくなったりするのでしょうか? 全体としては、C++は参照などあって、どいう場合にポインタ使うべきなのかそういう部分に混乱しているような気もします。 いろいろ質問してしまって、申し分けないですがなにか ひとつでも答えられるものがあれば回答してもらえると ありがたいです。

  • コンストラクタの順序?

    以下のソースに関して質問です。 /* library.h */ #pragma comment(lib, "library.lib") class A { public: A(); }; /* library.cpp */ #include "library.h" #include <list> class B { private: std::list<int> m_listi; public: void Func() { m_listi.push_back(0); //フリーズ return; } } g_CB; A::A() { g_CB.Func(); return; } /* test.cpp */ #include "library.h" A CA; int main() { return 0; } library.cppからlibrary.libをつくり、それをtest.cppで使用したところ、 ソースに示したところでプログラムがフリーズしてしまいます。 恐らくクラスBのm_listiが初期化される前にそれを使おうとしたためだと思います。 どうすればそれを避けられるでしょうか。。。

  • vectorを引数とする関数

    以下のようなプログラムにおいて、 #include <stdio.h> #include <cstdlib> #include <iostream> #include <vector> #include <fstream> #include <sstream> #include <map> using namespace std; double func(std::vector<double> *tmp2); int main(){ vector <double> tmp; tmp.resize(0); tmp.push_back(0.12458); tmp.push_back(-12.45); tmp.push_back(4.253); cout << func(&tmp) << endl; return 0; } double func(std::vector<double> *tmp2){ return tmp2[1]; } vector tmpをfuncに渡して、tmp[1]、すなわち、 -12.45が出力されるようにしたいと思います。 ですが、どうしてもコンパイルエラーが残ります。 どのようにすればよいでしょうか?

  • C++の話です。

    C++の話です。 静的メンバ変数としてクラスを宣言した場合、デストラクタが呼ばれていないようなのですが、呼ぶ方法はありませんか? できれば「new」「delete」を使わずできると理想的です。 分かる方教えていただけると助かります。 以下、サンプルコードです。 「デストラクタが呼ばれました」と出力されない上、デバッガを使って試してみましたが、やはり呼ばれていないようです。 #include<iostream> class Test{   public:     ~Test(){       std::cout<<"デストラクタが呼ばれました"<<std::endl;     } }; class A{   private:     static Test T; }; int main(){   A a;   return 0; }

  • クラスや構造体のarrayを作りたい。

    クラスや構造体のarrayを作りたい。 クラスや構造体のarrayを作りたいのですが、 以下の方法で正しいのでしょうか? ==================================== #include <string> #include <vector> class Test{ public:   std::string sono1;   int sono2;   bool sono3;   //コンストラクタ   Test(std::string tmp_sono1,int tmp_sono2,bool tmp_sono3){     sono1=tmp_sono1;     sono2=tmp_sono2;     sono3=tmp_sono3;   } }; void main(){   std::vector<Test> testObjArray;   testObjArray.push_back(*(new Test("てすと1",1,true)));   testObjArray.push_back(*(new Test("てすと2",2,false))); } ==================================== 質問1: コンストラクタ時、クラス内の変数へ引数の値を渡す時、 上記のようにtmpを作成する以外の方法はありますか? 質問2: push_back時、クラスをインスタンスしてvectorに渡すにはこのような記述であってるのでしょうか? 「testObjArray.push_back(*(new Test("てすと1",1,true)));」 一応問題なく動いているようなのですが心配です。 よろしくお願いします。

  • C++のファイルの分割について教えてください。

    分割したプログラムの書き方を練習中なのですが、 下のようなプログラムを書いて、ビルドしようとしたら失敗します。 どこが悪いのか、教えていただけないでしょうか? (5)\test30\Debug\test30.exe : fatal error LNK1120: 外部参照 1 が未解決です。 1>test30 - エラー 2、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== //test30.cpp #include <iostream> #include "sub.h" int main(void) { std::cout<<"メインプログラムです。"<<std::endl; sub1(); sub2(); return 0; } ------------------------------------------------------------- //sub1.cpp #include <iostream> void sub1(void) { std::cout<<"サブ1です。"<<std::endl; } ------------------------------------------------------------- //sub2.cpp #include <iostream> void sub1(void) { std::cout<<"サブ2です。"<<std::endl; } --------------------------------------------------------------- //sub.h void sub1(void); void sub2(void);

  • C++のプログラムについて教えてください。

    C++のプログラムについて教えてください。 以下のようなプログラムでコンパイルを行うと、エラーが起きてしまい、原因が分かりません。 OSはMac OS X 10.6.4です。 プログラム //************************************ //main.cpp #include <iostream> class test{ private: static int num; public: test(); int get_num(); }; test::test(){ num=0; } int test::get_num(){ return num; } int main(){ test t; int num = t.get_num(); std::cout<<num<<std::endl; return (0); } //*********************************** g++ -o main main.cppでコンパイルした結果 Undefined symbols: "test::num", referenced from: test::test() in ccYWvIdB.o test::test() in ccYWvIdB.o test::get_num() in ccYWvIdB.o ld: symbol(s) not found collect2: ld returned 1 exit status のようにエラーが起きます。 どなたか分かる方がいればお願いします。

  • 外部ファイルでのtemplate関数の実装方法

    外部ファイルでのtemplate関数の実装方法 sub.cppにtemplate関数を実装し、 main.cppで、sub.cppのtemplate関数を呼び出す、 みたいなことをやりたいのですが、 コンパイルは通りますが、リンクエラー?になってしまいます。 以下が上記のサンプルプログラムです。 //main.cpp #include <vector> #include <iostream> using namespace std; template <typename t_ret, typename t_array> t_ret sub_t(const t_array&); int main (int argc, char *argv[]) { vector<double> v; v.push_back(1.1); v.push_back(2.2); cout << sub_t<double, vector<double> >(v) << endl; return 0; } // sub.cpp #include <vector> using namespace std; template <typename t_ret, typename t_array> t_ret sub_t(const t_array& array) { return array[0]+array[1]; } //コンパイルログ main.o: In function `main': main.cpp:(.text+0x134): undefined reference to `double sub_t<double, std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> > const&)' collect2: ld returned 1 exit status make: *** [main] Error 1 どなたか、対処方法を教えてください。 宜しくお願いします。

  • STLのlistとrandを使うと異常終了します

    STLの勉強をしているものです。VisualC++6.0で正常に動作するプログラムをVusialC++2008ExpressEditionで動かしたら異常終了しました。色々調べていくと、乱数値をセットしたlistをマージするときに異常終了するようです。尚、異常終了するのはDebugビルドのときのみで、Releaseビルドのときは正常に動作します。異常終了するプログラムを以下に載せておきます。どなたかご教授お願い申し上げます。 #include<list> #include <time.h> #include <stdlib.h> using namespace std; int main(int argc, char* argv[]){ list<int> lst1, lst2; int i, n; srand(time(NULL)); for( i = 0 ; i < 5 ; i++ ){ n=rand() % 10; lst1.push_back( n ); } for( i = 0 ; i < 5 ; i++ ){ n=rand() % 10; lst2.push_back( n ); } lst1.merge( lst2 ); // リストをマージ ここで異常終了 return 0; }

専門家に質問してみよう