使用接口

时间:2012-07-03 08:35:44

标签: c++

我在重构的代码中有以下形式的函数:

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的对象,其中接口相同但句柄不同。

5 个答案:

答案 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;
    }
}