C++ c++;抽象基类和派生类的工厂函数的返回类型

C++ c++;抽象基类和派生类的工厂函数的返回类型,c++,c++11,return-value,factory,shared-ptr,C++,C++11,Return Value,Factory,Shared Ptr,假设一个抽象基类和它的派生类都需要工厂(我无法访问实际的构造函数)。在效率和代码风格方面,哪种结构是最好的 1) 让所有工厂返回一个共享的ptr。这是统一的,但会导致派生类的许多不必要的共享_ptr,因为它们在客户机代码中直接被取消引用 std::shared_ptr<Derived> createDerived(Argument arg) { return std::make_shared<Derived>(arg); } std::shared_ptr

假设一个抽象基类和它的派生类都需要工厂(我无法访问实际的构造函数)。在效率和代码风格方面,哪种结构是最好的

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

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);
}
std::shared\u ptr createDerived(参数arg)
{ 
返回标准::使_共享(arg);
}
std::shared_ptr createABC(参数arg)
{
if(suchAndSo(arg))
返回createDerived(arg);
其他的
返回nullptr;//或CreateSometherDerivedClass
}
int main()
{
参数Arg;
派生d=*createDerived(arg);
自动pAbc=createABC(arg);
}
2) 让派生类的工厂返回一个值,让ABC工厂返回一个共享ptr,该ptr是使用make_shared和派生类的复制构造函数构造的(这会导致许多复制构造函数调用)

Derived createDerived(参数arg)
{
导出的返回值(arg);
}
std::shared_ptr createABC(参数arg)
{
if(suchAndSo(arg))
返回make_shared(createDerived(arg));
其他的
返回nullptr;//或CreateSometherDerivedClass
}
int main()
{
参数Arg;
派生d=createDerived(arg);
自动pAbc=createABC(arg);
}

在ABC案例中,您可以简单地返回一个
唯一的\u ptr
,以避免
共享的\u ptr
的开销。但是,只有当
~AbstractBaseClass
是虚拟的时,这才是一个选项

通过返回
唯一\u ptr
,您允许调用者决定是否需要共享对象


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

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

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);
}
如果对象不可移动构造,并且优化器没有实现复制省略(任何合适的优化器都会实现),则返回值的工厂本身才会复制


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

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


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

您是否计划使用一些多态函数?@doctorlove如果没有多态函数(我假设您指的是虚拟函数),您就无法拥有抽象基类,你能吗?:)