2

我正在重构的代码中具有以下形式的功能:

A f()
{
    if(existing)
        return A();
    else
        return A(handle);
}

Safe Bool Idiom 稍后用于测试 A 是否与句柄相关联,即我们是否应该调用该对象的类方法,这些方法在内部需要一个有效的句柄才能执行。A 的方法是 const。

我想在这里返回一个接口 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 类型的对象,其中接口相同但句柄不同。

4

5 回答 5

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会照顾的。

于 2012-07-03T08:50:00.020 回答
2

我也会使用指针,但您可以使用引用:

A& f()
{
    if(existing)
    {
        static A a;
        return a;
    }
    else
    {
        static A a(handle);
        return a;
    }
}

但是,您完全了解其中的含义,对吗?即您不能重新分配引用并修改它意味着修改局部static变量。

于 2012-07-03T08:39:01.473 回答
1

从您的代码片段看来,您正在构造函数中的A对象f。在这种情况下,按值返回对象可能是您能做的最好的事情。编译器将使用返回值优化 ( RVO ) 并优化所有副本。

查看Dave Abrahams 的这篇关于按值传递和返回对象的文章。

A请注意,由于切片问题,如果您返回基类,此解决方案将不起作用。如果返回一个A对象没问题,那么这可能是最好的解决方案。

于 2012-07-03T08:40:49.993 回答
1

如果你能理解指针,那么就使用指针。如果你不能,那就坚持你所拥有的。看起来像你之前的那个人尽力避免指针。正如 betabandido 所说,编译器将充分利用它,即使它看起来很慢 - 在纸上。

接口是一种充分利用指针的设计模式。没有指针和强制转换就没有多大意义。

为了测试指针是否指向某个东西,有 NULL 值。如果您正在射击苍蝇,则无需推出大炮。

解释为什么你不喜欢现在的代码。也许问题并不严重。

于 2012-07-03T09:11:08.350 回答
0

返回指针是一种方法。

对我来说,另一种简单且原生的方法是在方法的签名中添加一个返回值。

int f(A & a)
{
    if(existing)
    {
        return ERROR_ALREADY_EXISTS;
    }
    else
    {
        A temp(handle);
        a = temp;
        return SUCCEEDED;
    }
}
于 2012-07-03T08:56:09.397 回答