我在重构的代码中有以下形式的函数:
A f()
{
if(existing)
return A();
else
return A(handle);
}
Safe Bool Idiom后来用于测试A是否与句柄相关联,即是否应该调用此对象的类方法,该方法需要内部有效的句柄来执行。 A的方法是常量。
我想在这里返回一个接口IA。因此我必须返回指针吗?如果是这样,我将使用boost共享指针。我可以测试指针是否指向某个东西。
有没有办法让我在这里使用引用?你会推荐这样的方法,还是认为boost :: shared_ptrs是要走的路?
更新
A来自IA。
我的编译器是gcc版本4.4.3。
此代码的最大问题是A用于与外部C API交互。因此,我希望使用IA接口作为我的Mock of A及其实现A的基础来模拟它。然后在上面的方法f()之外,我将其视为工厂,我将只使用IA指针。换句话说就是依赖注入。
所以A基本上是一个句柄和一组需要句柄的C API函数的接口。我可以有几个类型为A的对象,其中接口相同但句柄不同。
答案 0 :(得分:4)
我会返回一个std::unique_ptr< AI >
对象:
std::unique_ptr< AI > f()
{
if(existing)
return std::unique_ptr< AI >( new A() );
else
return std::unique_ptr< AI >( new A(handle) );
}
在上面的情况下,切片不会发生,编译器将移动 * 对象。
* 我假设你使用的是c ++ 11。
由于您没有使用c ++ 11,最简单的方法是使用boost::shared_ptrs
:
boost::shared_ptrs< AI > f()
{
if(existing)
return boost::shared_ptrs< AI >( new A() );
else
return boost::shared_ptrs< AI >( new A(handle) );
}
在这种情况下,您无需关注创建的对象是否以及何时被破坏。 boost::shared_ptrs
会照顾到这一点。
答案 1 :(得分:2)
我也会使用指针,但你可以也可以使用引用:
A& f()
{
if(existing)
{
static A a;
return a;
}
else
{
static A a(handle);
return a;
}
}
你完全了解其含义,对吗?即你不能重新分配引用并修改它意味着修改本地static
变量。
答案 2 :(得分:1)
在您的代码段中,您似乎正在构建函数A
中的f
个对象。在这种情况下,按值返回对象可能是您可以做的最好的事情。编译器将使用返回值优化(RVO)并优化所有副本。
Dave Abrahams检查此article有关按值传递和返回对象的信息。
请注意,如果由于slicing problem而返回A
的基类,则此解决方案将无效。如果返回A
对象很好,那么这可能是最佳解决方案。
答案 3 :(得分:1)
如果你能理解指针,那么使用指针。如果你不能,那么坚持你所拥有的。在你尽力避免指针之前看起来像那个人。正如betabandido所说,编译器将充分利用它,即使它似乎很慢 - 在纸面上。
接口是一种充分利用指针的设计模式。没有指针和铸造它就没有多大意义。
要测试指针是否指向某个东西,会有NULL值。如果你正在拍苍蝇,就不需要推出大炮。
解释为什么你不熟悉现在的代码。也许问题并不严重。
答案 4 :(得分:0)
返回指针是一种可行的方法。
对我来说,另一种简单而原生的方法是在方法的签名中添加一个返回值。
int f(A & a)
{
if(existing)
{
return ERROR_ALREADY_EXISTS;
}
else
{
A temp(handle);
a = temp;
return SUCCEEDED;
}
}