4

これらの静的メンバーによるc++クラスの初期化に問題があります。詳細については、私のコードを参照してください。

ソース

header.h

#ifndef HEADER_H
#define HEADER_H
#include <string>
using namespace std;
class Staff{ public: static string str;};
class Boss{ public: static string str;};
#endif

staff.cpp

#include "header.h"
string Staff::str = "(staff)";

boss.cpp

#include "header.h"
string Boss::str = "I call " + Staff::str;

main.cpp

#include <iostream>
#include "header.h"
int main(){cout << Boss::str << endl;}

そして、ここに異なる結果を持つ多くのコンパイルコードがあります:

プリコンパイル:

g++ -c boss.cpp
g++ -c staff.cpp
ar rcs lib.a boss.o staff.o
ar rcs rlib.a staff.o boss.o

コンパイル、実行、結果:

g++ main.cpp staff.cpp boss.cpp ; ./a.out
==> I call (staff)
g++ main.cpp boss.cpp staff.cpp ; ./a.out
==> segmentation fault (core dumped)
g++ main.cpp lib.a ; ./a.out
==> segmentation fault (core dumped)
g++ main.cpp rlib.a ; ./a.out
==>segmentation fault (core dumped)

コンパイル時に巨大なオブジェクトの順序と混同するのではなく、ライブラリアーカイブを使用したいと思います。それらを解決するのを手伝ってください。

ありがとうございました。

4

2 に答える 2

12

個別の変換単位での静的変数の初期化順序は定義されていません。2つのソースファイルは2つの別個の変換ユニットを構成し、それぞれが1つの変数を定義します。セグメンテーション違反は、まだ初期化されていないときにを使用Staff::strして初期化しようとしたときに発生する可能性があります。Boss::strStaff::str

これを解決するには、両方を同じ単一の翻訳単位で定義します。

#include "header.h"
string Staff::str = "(staff)";
string Boss::str = "I call " + Staff::str;

または、初期化を互いに独立させます。

std::string Staff::get_str() {
  return "(staff)";
}

string Staff::str = Staff::get_str(); 

string Boss::str = "I call " + Staff::get_str();

最初の2つの例から、初期化の順序はリンクの順序に関連しているように見えますが、それに依存してはなりません。

于 2012-08-11T03:36:53.513 に答える
4

個別の翻訳単位でのグローバル変数の初期化順序は定義されていません。それらを関数でラップして機能させることができます:

class Staff{ public: static & string str();};
class Boss{ public: static & string str();};

string & Staff::str()
{
  static string s = "(staff)";
  return s;
}

string & Boss::str()
{
  static string s = "I call " + Staff::str();
  return s;
}
于 2012-08-11T03:45:03.663 に答える