如何在trompeloeil的RETURN期望中返回std::unique_ptr?
如何在trompeloeil的RETURN期望中返回std::unique_ptr?
你遇到的这个问题其实很常见——因为std::unique_ptr是独占所有权的智能指针,它的拷贝构造函数被主动删除了,直接在RETURN里返回它的话,默认会触发拷贝操作,自然就会报出你看到的那个错误。不过别担心,trompeloeil完全支持移动语义,只要用对方式返回右值就能解决,下面给你两种实用的方案:
方案一:直接返回临时构造的std::unique_ptr
你可以直接在RETURN里用std::make_unique创建一个临时的std::unique_ptr对象。临时对象本身是右值,trompeloeil会自动用移动构造来处理它,不会触发拷贝:
REQUIRED_CALL( *ptr_mock, buildA() ) .RETURN( std::make_unique<A>(42) );
这种方式最直接,适合你只需要返回一个新构造的A对象的场景。
方案二:返回已存在的std::unique_ptr(需要用std::move)
如果你已经有一个预先创建好的std::unique_ptr变量,想要把它的所有权转移给调用方,就需要用std::move把它转换成右值,这样trompeloeil就能通过移动构造来返回它:
// 预先创建好的unique_ptr auto prebuilt_a = std::make_unique<A>(123); REQUIRED_CALL( *ptr_mock, buildA() ) .RETURN( std::move(prebuilt_a) );
⚠️ 注意:一旦执行了std::move,prebuilt_a就会变成空指针,它的所有权已经被转移走了,所以这个变量之后不能再被使用(除非你重新给它赋值)。
另外,我注意到你代码里C类的doStuff函数有个小错误:你在里面用了p_b->buildA(),但p_b只是构造函数的参数,C的私有成员是_b,正确的写法应该是_b->buildA(),不然编译的时候会报错找不到p_b这个变量哦。
最后给你贴出修改后的main函数参考:
int main() { auto mock = std::make_unique<MockB>(); auto ptr_mock = mock.get(); C c{ std::move(mock) }; REQUIRED_CALL( *ptr_mock, buildA() ) .RETURN( std::make_unique<A>(42) ); c.doStuff(); return 0; }
内容来源于stack exchange
相关产品推荐
相关产品推荐

