C++ 调用模板化成员函数与模板化全局函数在通用工厂中创建对象

C++ 调用模板化成员函数与模板化全局函数在通用工厂中创建对象,c++,function,templates,pointers,C++,Function,Templates,Pointers,在网上搜索了工厂模式的不同方法之后,我已经实现了我自己的版本,我对此非常满意。Register成员函数为模板类型创建一个函数指针,使用索引作为键将其存储在std::map中。下面的代码编译和运行起来没有任何麻烦(64位Windows 7,代码::Blocks 10.05和GCC) \ifndef对象\u工厂\u水电站 #定义对象\u工厂\u水电站 #包括 命名空间内部{ 模板 BaseType*CreateFunction(){ 返回新的ObjectType; } } 模板 类对象工厂{ 公众:

在网上搜索了工厂模式的不同方法之后,我已经实现了我自己的版本,我对此非常满意。Register成员函数为模板类型创建一个函数指针,使用索引作为键将其存储在std::map中。下面的代码编译和运行起来没有任何麻烦(64位Windows 7,代码::Blocks 10.05和GCC)

\ifndef对象\u工厂\u水电站
#定义对象\u工厂\u水电站
#包括
命名空间内部{
模板
BaseType*CreateFunction(){
返回新的ObjectType;
}
}
模板
类对象工厂{
公众:
ObjectFactory();
模板
布尔寄存器(常量索引类型和索引);
bool注销(const IndexType&index);
BaseType*创建(常量索引类型和索引);
私人:
typedef BaseType*(*creationCallback)();
typedef std::map注册表;
登记处;
//私人:
//模板
//BaseType*CreateFunction();
};
模板
ObjectFactory::ObjectFactory(){
registry.clear();
}
模板
模板
bool ObjectFactory::Register(常量索引类型和索引){
if(registry.find(index)!=registry.end()
返回false;
注册表[索引]=&内部::CreateFunction;

//注册表[index]=&CreateFunction;创建函数应为静态成员:

template<typename ObjectType> static BaseType* CreateFunction();

编辑:要消除一些混淆,请执行以下操作:

这里的问题主要在于语法。模板和
private
在这里并不重要,所以让我们简化一下情况:

struct ObjectFactory {
    void CreateFunction() {std::cout << "message";}
    void AnotherFunction()
    {
        ... = &CreateFunction; // what's that?
    }
};
struct ObjectFactory{

void CreateFunction(){std::cout创建函数应该是静态成员:

template<typename ObjectType> static BaseType* CreateFunction();

编辑:要消除一些混淆,请执行以下操作:

这里的问题主要在于语法。模板和
private
在这里并不重要,所以让我们简化一下情况:

struct ObjectFactory {
    void CreateFunction() {std::cout << "message";}
    void AnotherFunction()
    {
        ... = &CreateFunction; // what's that?
    }
};
struct ObjectFactory{
void CreateFunction(){std::cout在我们的文件中,我们匿名化我们的名称空间:

// namespace internal {  
   namespace          {
    template<typename BaseType, typename ObjectType> 
    BaseType* CreateFunction() { ... }  
}
//命名空间内部{
名称空间{
模板
BaseType*CreateFunction(){…}
}
现在可以按照最初编写的方式调用非静态函数,而无需命名空间限定:

// registry[index] = &internal::CreateFunction<ObjectType>;  
   registry[index] =           &CreateFunction<ObjectType>; 
//注册表[索引]=&internal::CreateFunction;
注册表[索引]=&CreateFunction;
文件范围的
CreateFunction
函数对于翻译单元之外的代码不可见,并且仅由类
ObjectFactory
调用

这与问题中提出的
CreateFunction
(在
ObjectFactory
中)的
private
访问说明符非常接近。

在我们的文件中,我们将名称空间匿名化:

// namespace internal {  
   namespace          {
    template<typename BaseType, typename ObjectType> 
    BaseType* CreateFunction() { ... }  
}
//命名空间内部{
名称空间{
模板
BaseType*CreateFunction(){…}
}
现在可以按照最初编写的方式调用非静态函数,而无需命名空间限定:

// registry[index] = &internal::CreateFunction<ObjectType>;  
   registry[index] =           &CreateFunction<ObjectType>; 
//注册表[索引]=&internal::CreateFunction;
注册表[索引]=&CreateFunction;
文件范围的
CreateFunction
函数对于翻译单元之外的代码不可见,并且仅由类
ObjectFactory
调用


这与问题中提出的
CreateFunction
(从
ObjectFactory
)的
private
访问说明符非常接近。

BaseType*CreateFunction(){return new ObjectType;}
应该是
std::unique\u ptr CreateFunction(){std::unique\u ptr p(new ObjectType());return p;}
。只要对
删除说“不”
。如果你读了我文章的最后一段,你就会发现我已经计划使用boost::shared\u ptr。我已经有相当一部分内存泄漏,所以我同意你的上一句话。还提醒我应该阅读std::unique\u ptr,所以谢谢:)
BaseType*CreateFunction(){return new ObjectType;}
应该是
std::unique_ptr CreateFunction(){std::unique_ptr p(new ObjectType());return p;}
。只要说“不”删除
。如果你读了我文章的最后一段,你会发现我已经计划使用boost::shared_ptr。我已经有相当一部分内存泄漏,所以我同意你的上一句话。还提醒我应该阅读std::unique_ptr,所以谢谢:)代码被注释掉了,因为这是最初的方法。新方法使用“这是在内部名称空间中声明的全局函数。@NordCoder我理解您的问题是“我的注释代码不工作;我如何修复它?”对不起,我将尝试重新表述我的问题。我刚刚尝试过,它工作得很好,非常感谢:)我不明白为什么这应该是无效语法(即使GCC告诉我是这样)或者为什么私有成员函数不起作用。也许GCC做的事情与MS Visual Studio相同?将函数指针typedef声明为typedef BaseType*(ObjectFactory::*creationCallback)();反而会生成更复杂的错误。对垃圾邮件表示歉意,但这确实是我的问题,我只是选择注释掉一种方法,以避免重复代码来显示两种方法。不过可能会更清楚。对。我想我明白了,感谢您的澄清。那么正确的语法是什么?再考虑一下它,我想我可能能够使用boost::function:
typedef std::map Registry;Registry Registry;//…Registry[index]=&ObjectFactory::CreateFunction;//…return Registry[index](*this,void);
不确定这是否有效(我目前还不是boost专家)…注意,我在这里也使用boost::shared\u ptr(我同时设法让它工作起来)。代码被注释掉了,因为这是最初的方法。新的方法使用内部命名空间中声明的全局函数。@NordCoder我理解你的问题是“我注释掉的代码不工作;我如何修复它?”抱歉,我将尝试重新编写