0

次のことを考慮してください: 2 つのクラス (A、B) があり、どちらも単一のヘッダー ファイル (H) を使用します。B をオブジェクト ファイルにプリコンパイルしてから、B の関数を呼び出すバイナリに A をコンパイルします。

ここでヘッダー ファイルを変更し、A を再コンパイルします。これにより、ガベージ出力が生成されます。私の質問は、そもそもコンパイラがこれを許可したのはなぜですか?

以下の具体例:

cat.h

#include <string>
using namespace std;
class cat_bus;

class catStr {
  private:
    string *a;
  public:
    catStr(string *a)
    {
      this->a = a;
    }
    string chars()
    {
      return a->c_str();
    }
};

class cat {
   friend class cat_bus;
   private:
   catStr a;
   //catStr z; //version X +1
   catStr b;
   catStr c;
   catStr d;
   public :
   cat()
   :a(new string("str1")),
    //z(new string("strz")), //version X +1
    b(new string("str2")),
    c(new string("str3")),
    d(new string("str4"))
  {
  }
};

class cat_bus
{
  private:
    cat myCat;
  public:
    string getA()
    {
      return myCat.a.chars();
    }
    string getB()
    {
      return myCat.b.chars();
 }
    string getC()
    {
      return myCat.c.chars();
    }
};

ユーザー.cpp

#include <iostream>
#include "cat.h"
using namespace std;

void userLibA()
{
   cat_bus catbus;
   cout <<"\nA:"<< catbus.getA() << "\n";
}

void userLibB()
{
   cat_bus catbus;
   cout << "B:"<< catbus.getB()<<"\n";
}

void userLibC()
{
   cat_bus catbus;
   cout << "C:" <<catbus.getC()<<"\n";
}

user.h

void userLibA();

void userLibB();

void userLibC();

main.cpp

#include <iostream>
#include "user.h"
#include "cat.h"
using namespace std;
int main ()
{
  userLibA();
  userLibB();
  userLibC();
  cat_bus catbus;
}

手順 コンパイル ユーザー:

g++ -c user.cpp

メインをコンパイルします。

g++ main.cpp user.o

メインを実行:

./a.out

生成:

A:str1
B:str2
C:str3

cat.h のコメントをアンコメントします。main を再コンパイルして実行します。現在、次のものが生成されます:

A:str1
B:strz <<<< This line is garbage
C:str3

これはメモリ位置に直接アクセスしているように思えますが、リンカはシンボル名で行くべきではありませんか??

4

0 に答える 0