在类的单元测试中,我尝试通过显式调用空构造函数来声明一个类变量,并将其传递给一个函数,该函数除了对我声明的类型的接口的引用之外,但编译器会产生错误。当我在没有任何显式构造函数调用的情况下声明它时,函数接受它。
请参阅以下代码:
//classundertest.h
class IController;
class CClassUnderTest
{
public:
CClassUnderTest() {}
virtual ~CClassUnderTest() {}
unsigned int Run(IController & controller);
};
//testclassundertest.h
#include "UnitTest++.h"
#include "classundertest.h"
#include "icontroller.h"
class CTestController : public IController
{
public:
CTestController() : IController() {}
virtual ~CTestController() {}
virtual void Play(unsigned int i) {}
};
struct CClassUnderTestFixture
{
CClassUnderTest classUnderTest;
};
TEST_FIXTURE(CClassUnderTestFixture, RunTest)
{
CTestController controllerA;
CHECK_EQUAL(classUnderTest.Run(controllerA), 105U);
CTestController controllerB();
CHECK_EQUAL(classUnderTest.Run(controllerB), 105U);
}
编译器认为controllerB是构造函数的引用:
错误:没有匹配函数来调用`CClassUnderTest :: Run(CTestController(&)())' 错误:候选者是:unsigned int CClassUnderTest :: Run(IController&)
我很困惑为什么编译器在实例化controllerB时不允许我调用构造函数,特别是当生产代码看起来没问题时呢?
答案 0 :(得分:6)
这一行:
CTestController controllerB();
是函数的声明,它不带任何内容并返回CTestController
。对于默认构造,您必须简单地省略括号。
这与称为“最令人烦恼的解析”的东西有关。考虑:
struct S {};
int main()
{
S s(S()); // copy construct a default-constructed S ...?
}
这不起作用。这将s
声明为一个函数,它接受一个不带任何内容的函数的指针,并返回一个返回S的S.为了解决这个问题,你可以使用一组额外的括号:
struct S {};
int main()
{
S s((S())); // copy construct a default-constructed S :)
}