c ++为Abstract Base Classes和Derived类返回工厂函数的类型

时间:2016-11-23 12:04:33

标签: c++ c++11 return-value factory shared-ptr

假设我需要为抽象基类及其派生类创建两个工厂(我无法访问实际的构造函数)。在效率和代码风格方面哪个是最好的结构?

1)让所有工厂返回shared_ptr。这是统一的,但导致派生类有许多不必要的shared_ptrs,因为它们在客户端代码中被直接取消引用。

std::shared_ptr<Derived> createDerived(Argument arg) 
{ 
    return std::make_shared<Derived>(arg); 
}

std::shared_ptr<AbstractBaseClass> createABC(Argument arg)
{
    if (suchAndSo(arg))
        return createDerived(arg);
    else
        return nullptr; // or createSomeOtherDerivedClass
}

int main()
{
    Argument Arg;
    Derived d = *createDerived(arg);
    auto pAbc = createABC(arg);
}

2)让派生类的工厂返回一个值,让ABC工厂返回一个共享的ptr,它是用make_shared和Derived的复制构造函数构造的(导致许多复制构造函数调用)

Derived createDerived(Argument arg)
{
    return Derived(arg);
}

std::shared_ptr<AbstractBaseClass> createABC(Argument arg)
{
    if (suchAndSo(arg))
        return make_shared<AbstractBaseClass>(createDerived(arg));
    else
        return nullptr; // or createSomeOtherDerivedClass
}

int main()
{
    Argument Arg;
    Derived d = createDerived(arg);
    auto pAbc = createABC(arg);
}

2 个答案:

答案 0 :(得分:3)

在ABC案例中,您只需返回unique_ptr即可避免shared_ptr的开销。但是,仅当~AbstractBaseClass为虚拟时才可以选择该选项。

通过返回unique_ptr,允许调用者决定是否需要共享该对象。

当返回具体类型的对象时,返回值确实是一个很好的选择。这避免了动态分配的成本。

  

导致许多复制构造函数调用

如果对象不是可移动构造的,并且优化器没有实现复制省略(任何像样的优化器那样做),则返回工厂本身的值只会复制。

您可以实现返回工厂的抽象指针,而无需委托给返回工厂的值,而是直接构造对象以避免该副本(移动)。

答案 1 :(得分:0)

两个工厂函数都应该返回简单的指针。共享指针应该应用于他们的结果。

在逻辑上,使用工厂方法选择适当的构造函数与管理对象所有权(通过共享指针)不同。