3

我已经被这件事难住了好几天了。我正在对我的一个班级进行单元测试,以确保一切正确。

但是,在比较对象的名称时,我遇到了一个非常奇怪的“错误”。当我调用构造函数时设置名称。根据我传入的注释正确设置了名称。但是在这种情况下,BOOST_CHECK 失败

为了说明这有多奇怪,以下是调试器中两个字符串的值:

Fdim.name() // "F Diminished"
BOOST_CHECK(Fdim.name() == "F Diminished");  // this fails

以下是两个字符串的规格,取自调试器:

Fdim.name() 
// size - 12, capacity - 15, 
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]

"F Diminished" stored inside a variable (to see specs of string)
// size - 12, capacity - 15,
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]

如您所见,字符串是相同的,但 == 和 .compare 都失败了。

这是更奇怪的事情:

std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r);       // RETURNS 0, everytime
BOOST_CHECK(val == 0);             // fails 
BOOST_CHECK(val == ((unsigned) 0));// fails

我完全傻眼了。当我比较字符串时 val 总是返回 0 (所以它们相等)但是当我比较时 val != 0 ?

有谁知道是什么问题?我应该知道的字符串是否有任何属性可能会导致此比较检查失败?

编辑* * * 字符串被存储为 std::string,我没有使用 char* 或 cstring。成员 _name 是 std::string。

这是升压输出:

c:/directory etc(64): error in "ChordIdentification": check val == 0 failed
c:/directory etc(65): error in "ChordIdentification": check n == r failed
c:/directory etc(66): error in "ChordIdentification": check val == ((unsigned) 0) failed
c:/directory etc(67): error in "ChordIdentification": check Fdim.name() == "F Diminished" failed

这是测试用例的代码,只是为了确保人们知道 val、n 和 r 是什么:

BOOST_AUTO_TEST_CASE(ChordIdentification)
{
MAKE_NOTE(Db, 'D', FLAT);   // macro that creates a note
MAKE_NOTE(F, 'F', NATURAL);
MAKE_NOTE(Ab, 'A', FLAT);
MAKE_NOTE(Cb, 'C', FLAT);

Chord DbMajor7 = Chord(Cb, Ab, F, Db);
Chord Fdim = Chord(Ab, Cb, F);

CHORD_TEST(DbMajor7, "Db Dominant7", MAJ, THIRD_INVERSION, DOMINANT7); macro of several boost tests, checking members. This test passes completely for this instance of chord. name() check is passed
std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r);
//if (val == 0)
BOOST_CHECK(val == 0);
BOOST_CHECK(n == r);
BOOST_CHECK(Fdim.name() == std::string("F Diminished"));    // these strings fail to compare. no idea why, lengths are same, chars same?????
BOOST_CHECK(std::strcmp(Fdim.name(), "F Diminished") == 0);
CHORD_TEST(Fdim, "F Diminished", DIM, FIRST_INVERSION, DIMINISHED); // partially successful, again the string comparison is responsible for this
}
4

2 回答 2

4

我终于发现了为什么会这样。这与调试器无法确定它试图评估的子类的实例有关。

和弦是通过具有多态键的映射来识别的,具有抽象基类 (Composite_Key)、子 (Composite_Key_2Intervals) 和来自该子的子 (Composite_Key_3Intervals)

失败的事实是,任何关于键是否确实是 3 个间隔或 2 的测试总是返回 true,因为 3intervals : 2intervals。编译器无法理解这一点,并且总是返回在查找表中找到的错误值。

此外,地图从未在调试器模式下排序,因此插入键的顺序保持不变。然而实际上它们正在被重新洗牌,这导致调试时的整个评估是完全错误的。

为了解决这个问题,我现在确保这两个类只从抽象基类继承,这样它们就不会以任何方式相互关联。现在所有测试都通过了,一切都恢复了。

这个问题的原因仅仅是调试器。它没有进行适当的评估。

于 2013-01-20T21:11:35.767 回答
2

如果我们看这个:

BOOST_CHECK(Fdim.name() == "F Diminished")

那么 Fdim.name() 是一个 C 风格的字符串,我希望,因此只是一个指向字符数组的指针 - 该字符数组的地址(很可能)与您的BOOST_CHECK().

您可以通过以下方式修复它:

BOOST_CHECK(Fdim.name() == string("F Diminished"))

或者

BOOST_CHECK(strcmp(Fdim.name(), "F Diminished") == 0)
于 2013-01-20T19:40:40.863 回答