析构函数中的 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; 
 }