2 つの C++ ファイルに同じ名前のクラスの異なる定義がある場合、それらをコンパイルしてリンクすると、警告がなくても何かがスローされます。例えば、
// a.cc
class Student {
public:
std::string foo() { return "A"; }
};
void foo_a()
{
Student stu;
std::cout << stu.foo() << std::endl;
}
// b.cc
class Student {
public:
std::string foo() { return "B"; }
};
void foo_b()
{
Student stu;
std::cout << stu.foo() << std::endl;
}
g++ を使用してコンパイルおよびリンクすると、どちらも "A" を出力します (コマンド ラインの順序で a.cc が b.cc より前にある場合)。
同様のトピックがここにあります。名前空間がこの問題を解決すると思いますが、リンカーが警告を出さない理由がわかりません。また、クラスの 1 つの定義に、別のクラスでは定義されていない追加の関数がある場合、b.cc が次のように更新されたとします。
// b.cc
class Student {
public:
std::string foo() { return "B"; }
std::string bar() { return "K"; }
};
void foo_b()
{
Student stu;
std::cout << stu.foo() << stu.bar() << std::endl;
}
それから stu.bar() はうまくいきます。このような状況でコンパイラとリンカーがどのように機能するかを教えてくれる人に感謝します。
追加の質問として、クラスがヘッダー ファイルで定義されている場合、そのような状況を回避するために、常に名前のない名前空間でラップする必要がありますか? 副作用はありますか?