使用接口

Working with interfaces

本文关键字:接口      更新时间:2023-10-16

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

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

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

我想在这里返回一个接口 IA。因此,我必须返回指针吗?如果是这样,我将使用提升共享指针。我可以测试指针是否指向某物。

我有什么办法可以在这里使用参考文献吗?你会推荐这种方法,还是你认为 boost::shared_ptrs 是要走的路?

更新

A 派生自 IA。

我的编译器是 gcc 版本 4.4.3。

我对这段代码的最大问题是 A 用于与外部 C API 交互。因此,我希望使用 IA 接口作为我的 A 模拟及其实现 A 的基础来模拟它。然后,在上面的方法f()之外,我将其视为工厂,我将只使用IA指针。换句话说,依赖注入。

所以 A 基本上是一个句柄和一个接口,用于一组需要句柄的 C API 函数。我可以有几个类型 A 的对象,其中接口相同但句柄不同。

我会返回一个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会处理这个问题。

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

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

不过,您完全意识到其含义,对吧? 也就是说,你不能重新分配引用,修改它意味着修改局部static变量。

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

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

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

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

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

要测试指针是否指向某物,存在 NULL 值。如果你在射击苍蝇,就不需要推出大炮。

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

返回指针是一种方法。

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

int f(A & a)
{
    if(existing)
    {
        return ERROR_ALREADY_EXISTS;
    }
    else
    {
        A temp(handle);
        a = temp;
        return SUCCEEDED;
    }
}