3

やや学術的な質問ですが、単体テストを書いているときにこれに遭遇しました。

私の単体テスト フレームワーク (UnitTest++) では、フィクスチャとして機能する構造体を作成できます。通常、これらはファイル内のテストに合わせてカスタマイズされるため、単体テスト ファイルの先頭に配置します。

//Tests1.cpp

struct MyFixture {  MyFixture() { ... do some setup things ...} };

TEST_FIXTURE(MyFixture, SomeTest)
{
  ...
} 

//Tests2.cpp

struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}};

 TEST_FIXTURE(MyFixture, SomeOtherTest)
 {
  ...
 }

ただし、最近 (少なくとも VS2005 では) 同じ名前を使用してフィクスチャ構造体に名前を付けると (したがって、構造体の 2 つのバージョンが同じ名前で存在するようになりました)、バージョンの 1 つが静かにスローされることがわかりました。コンパイラを /W4 (最高の警告レベル) に設定していて、警告が表示されないため、これはかなり驚くべきことです。これは名前の衝突であり、名前空間が発明された理由だと思いますが、それぞれの単体テスト フィクスチャを個別の名前空間にラップする必要があるのでしょうか? もっと基本的なものを見逃していないことを確認したいだけです。

これを修正するより良い方法はありますか? シンボルの重複エラーか何かが表示されるべきではありませんか?

4

3 に答える 3

8

クラスを匿名の名前空間に固定してみてください。ファイルごとに新しい名前空間を作成して名前を付けるよりも不快ではないかもしれません。

VS2005 と Cpp ユニットにはアクセスできませんが、これは機能する可能性があります..

//Tests1.cpp
namespace
{
struct MyFixture {  MyFixture() { ... do some setup things ...} };
}

TEST_FIXTURE(MyFixture, SomeTest)
{
  ...
} 


//Tests2.cpp
namespace
{
struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}};
}

TEST_FIXTURE(MyFixture, SomeOtherTest)
{
 ...
}
于 2010-01-15T22:09:59.923 に答える
2

コンパイラは、一度に 1 つのコンパイル単位でのみ動作します。これは、ソース ファイルとそれに #include されるすべてのものになります。クラスは異なるファイルにあるため、競合はありません。

リンカーはすべてをまとめますが、クラス定義については認識しないため、競合も発生しません。

C の時代には、同じ名前の 2 つの異なる関数があることをリンカが認識し、エラー メッセージを生成することは非常に一般的でした。C++ のインライン関数とテンプレートでは、それができなくなりました。異なるコンパイル ユニットには同じ関数の重複が含まれることが多いため、リンカーはそれらが同じであると想定します。

于 2010-01-15T22:11:27.433 に答える
0

これは基本的に、ヘッダー ファイルでクラスを定義する必要があるという事実の結果であり、各オブジェクト ファイルでクラスの定義が重複することになります。そのため、C++ リンケージを処理できるリンカは、冗長なクラス宣言をまとめて、クラスが 1 回だけ宣言されたふりをする必要があります。

複数のオブジェクトに含まれる単一のクラスと、複数のオブジェクトに含まれる同じ名前の複数のクラスをリンカが区別する方法はありません。

これを回避するには、名前空間 (またはより良い言語) を使用する必要があります。

于 2010-01-15T22:11:15.110 に答える