次のことを考慮してください: 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
これはメモリ位置に直接アクセスしているように思えますが、リンカはシンボル名で行くべきではありませんか??