You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GMock的MOCK_METHOD模拟返回引用的重载类型转换运算符?

模拟返回引用的类型转换运算符时的编译错误分析与修复

问题场景

你有一个重载了返回引用类型的类型转换运算符的类,示例如下:

class MyClass : public MyClassInterface {
  public:
    virtual ~MyClass() override;
    operator const int&() const override {
        return m_value;
    }
  private:
    int m_value{};
};

可以通过int val = myclass;的方式获取值。

你参考了以下可正常编译的gmock模拟示例:

class Foo {
  public:
virtual ~Foo() {}
virtual int operator[](int index) = 0;
};

class MockFoo : public Foo {
  public:
MOCK_METHOD(int, BracketOp, (int index));
virtual int operator[](int index) override { return BracketOp(index); }
};

但适配自己的需求时写出了如下代码,出现编译错误:

class Bar {
  public:
virtual ~Bar() {}
virtual operator const int&() = 0;
};

class MockBar : public Bar {
  public:
MOCK_METHOD(int, RefOp, ());
virtual operator const int&() override { return RefOp(); }
};

错误信息

error: returning reference to temporary [-Werror=return-local-addr]
 1173 |     virtual operator const int&() override { return RefOp(); }
      |                                                     ~~~~~^~

错误原因

  • RefOp()被声明为返回值类型int,当你在类型转换运算符中返回它的结果时,会生成一个临时int对象。而类型转换运算符要求返回const int&引用,引用绑定到这个临时对象后,临时对象会在当前语句结束后立即销毁,导致引用变成悬空引用,这就是编译器抛出错误的核心原因。
  • 对比MockFoo的情况:operator[]和BracketOp都返回值类型int,直接返回值不存在引用绑定临时对象的问题,因此可以正常编译。

修复方案

需要让模拟方法RefOp()的返回类型与纯虚运算符的返回类型一致,即返回const int&,同时要确保引用指向的对象具有足够长的生命周期(比如Mock类内部持有成员变量,或通过gmock动作返回对外部持久对象的引用)。

修改后的正确代码

class Bar {
  public:
virtual ~Bar() {}
virtual operator const int&() = 0;
};

class MockBar : public Bar {
  public:
    // 将RefOp的返回类型改为const int&,匹配运算符的返回类型
    MOCK_METHOD(const int&, RefOp, ());
    virtual operator const int&() override { 
        return RefOp(); 
    }

  private:
    // 可选:如果需要模拟固定值,可持有一个成员变量供引用返回
    int m_mock_value{};
};

使用示例

通过gmock的ReturnRef动作指定返回的引用对象,确保对象生命周期足够:

MockBar mock_bar;
int test_val = 42;
// 指定RefOp返回test_val的引用
EXPECT_CALL(mock_bar, RefOp())
    .WillRepeatedly(ReturnRef(test_val));

// 使用类型转换
const int& val_ref = mock_bar;
int val = mock_bar;

内容的提问来源于stack exchange,提问作者Ingo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:47:41