我有以下课程:
class D1;
class D2;
class Base
{
Public:
Base();
virtual ~Base() { if (instance) delete instance; }
static Base* GetInstance();
virtual int Get() = 0;
virtual int Set(const int val) = 0;
private:
static Base* instance;
};
Base *Base::instance = nullptr;
Base* Base::GetInstance()
{
if (some_condition)
return new D1;
else
return new D2;
}
class D1 : public Base
{
public:
...
virtual int myD1Method()
{
...
}
int Get()
{
...
}
int Set(const int val)
{
...
}
private:
// members...
};
class D2 : public Base
{
public:
...
int Get()
{
...
}
int Set(const int val)
{
...
}
private:
// members...
};
为了测试我的D1类,我使用谷歌模拟框架创建了一个模拟类,如下所示:
class MockD1 : public D1
{
protected:
using D1::MyD1Method;
MockD1() : base(Base::GetInstance()) {}
MOCK_METHOD0(MyD1Method, int())
private:
Base *base;
};
TEST(MockTest, TestD1)
{
MockD1 md1;
EXPECT_CALL(md1, MyD1Method()).WillRepeatedly(Return(10));
EXPECT_EQ(md1.Set(10), NO_ERROR);
EXPECT_EQ(md1.Get(), 10);
}
测试似乎工作正常。但是,我在测试结束时遇到了总线错误。当我在gdb中单步执行时,它看起来好像卡在基类析构函数的循环中,最终导致总线错误。我会很感激我对错误的看法。提前谢谢。
答案 0 :(得分:1)
问题在于这个析构函数:
virtual ~Base() { if (instance) delete instance; }
它与GMock无关。
delete instance
正在调用Base::~Base()
- 和Base::~Base()
调用delete instance
- 这是您正在观察的无限循环。
正确的解决方案是不使用单身人士。你可以改用一些工厂。
您还可以尝试在删除实例之前使实例无效 - 这应该有效 - 但仍然 - Base的每个实例都是Base :: instance的所有者(即控制其生命周期)并不是好设计:
virtual ~Base()
{
Base* instanceToDelete = instance;
instance = nullptr;
if (instanceToDelete) delete instanceToDelete;
}