析构函数中的 GMock 总线错误
GMock bus error in destructor
我有以下 classes:
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,我使用 google 模拟框架创建了一个模拟 class,如下所示:
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 中逐步执行时,它看起来好像陷入了基本 class 析构函数的循环中,最终导致总线错误。对于我做错了什么的任何意见,我将不胜感激。提前致谢。
问题出在这个析构函数上:
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;
}
我有以下 classes:
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,我使用 google 模拟框架创建了一个模拟 class,如下所示:
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 中逐步执行时,它看起来好像陷入了基本 class 析构函数的循环中,最终导致总线错误。对于我做错了什么的任何意见,我将不胜感激。提前致谢。
问题出在这个析构函数上:
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;
}