首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ createObject()工厂

C++ createObject()工厂
EN

Stack Overflow用户
提问于 2013-01-02 04:03:37
回答 4查看 732关注 0票数 2

我想用简单的C++语法创建一个简单的工厂方法:

代码语言:javascript
复制
void *createObject(const char *str,...)
{
  if(!strcmp("X",str))
     return new X(...);
}

我不知道它的语法是什么。我一直在研究模板元编程并使用mpl::vectors,但我不确定如何将此语法传递下去。如果可能的话,我真的想避免使用C va_lists,而是使用像上面那样干净的语法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-01-05 20:58:39

我最终使用的解决方案是创建0,N个带有模板化参数的单例。它在N= 8的情况下工作得很好。有点难看,但只需要做一次。

票数 0
EN

Stack Overflow用户

发布于 2013-01-02 04:08:23

在C++11上这将是一种更好的方法

代码语言:javascript
复制
template< typename ...Args >
std::shared_ptr<void> createObject( std::string const& name, Args&& ...args )
{
    if( name == "X" )
    {
        return try_make_shared< X >( std::forward< Args >( args )... );
    }
    /* other cases here*/

    return nullptr;
}

template< typename T, typename ...Args >
typename std::enable_if<
    std::is_constructible< T, Args >::value
  , std::shared_ptr< T >
>::type try_make_shared( Args&&... args )
{
    return std::make_shared< X >( std::forward< Args >( args )... );
}
template< typename T, typename ...Args >
typename std::enable_if<
    !std::is_constructible< T, Args >::value
  , std::shared_ptr< T >
>::type try_make_shared( Args&&... args )
{
    throw std::invalid_argument( "The type is not constructible from the supplied arguments" );
    return nullptr;
}

代码的不同之处在于

  • 它使用可变模板函数而不是省略号参数,因此参数的数量和类型在编译时仍然可用(您不会放松类型检查)。此外,你可以使用非POD类型调用这个函数。
  • 它返回一个shared_ptr<void>而不是一个普通的void*。这允许您在所有对对象的引用消失后,从工厂内部控制如何清除该对象。用户不需要知道或关心是否应该调用标准delete或工厂中的deleteObject方法。

更新:对于那些建议unique_ptr的人,你可以阅读here,了解shared_ptr带来的可能性。只返回指向new-ly分配的对象的指针的受限工厂可以而且应该使用unique_ptr

票数 8
EN

Stack Overflow用户

发布于 2013-01-02 04:26:05

除了关于如何使用漂亮的C++11可变模板创建对象的代码(如K-ballo的答案中所示),这个答案还展示了我将如何处理项目中的一组类。这种方法是一个很大的技巧,只有当你知道自己在做什么时才被推荐,然而,当你向项目添加新类时,你只需要将它们添加到一个列出所有类的文件中,所以如果项目变得很大,它有助于保持概述。

仅当您必须多次列出类时才使用此方法,例如,如果您还希望拥有一个std::string className()函数,例如,在不使用C++运行时类型信息的情况下返回类的名称。每个这样的函数都需要列出项目中的所有类,其实现方式与以下方法类似。

类.h

代码语言:javascript
复制
/* For every class in your project which should be creatable through your
 * factory, add a line here. */
CLASS(Foo)
CLASS(Bar)
CLASS(Baz)

factory.cpp

代码语言:javascript
复制
template< typename ...Args >
std::shared_ptr<void> createObject( std::string const& name, Args&& ...args )
{
    // Define what code to insert for every class:
#define CLASS(T) \
    else if(name == #T) \
        return std::make_shared<T>(std::forward(args)...);

    // List all cases:
    if(0) /*do nothing*/;  // <-- needed because the macro uses else if
#include "classes.h"
#undef CLASS

    return nullptr;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14113741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档