【问题标题】:Factory Pattern: typedef Class *(createClassFunction)(void)工厂模式:typedef Class *(createClassFunction)(void)
【发布时间】:2014-08-22 09:55:41
【问题描述】:

typedef Class *(createClassFunction)(void)(或其他变体是typedef Class* (__stdcall *CreateClassFunction)(void))代表什么? 这是什么意思?我该怎么解释呢? 尤其是在工厂模式的上下文中......

【问题讨论】:

  • 阅读函数指针。
  • 定义了一个函数指针类型createClassFunction,它返回指向Class的指针,这样你就可以声明一个createClassFunction类型的变量,并分配一个该函数的实际实现,这样每次调用时,例如实例化 Class 对象。
  • 完成这个:__stdcall 修饰符告诉编译器使用特定的调用约定(如何传递参数,谁负责堆栈清理)。然而,这对于高级代码通常是完全不感兴趣的,编译器通常会为您选择正确的。除此之外,如果可能的话,通常还可以通过编译器标志告诉编译器将每次调用都设为__fastcall;未指定调用约定的另一个原因。

标签: c++ class typedef factory-pattern instances


【解决方案1】:

Reading C type expressions

createClassFunction 是一个不带参数并返回 Class * 的函数的 typedef。

通过该声明,指向此类函数的指针显然可以充当Class工厂。用法可能如下:

// the class factory
Class * MostTrivialFactoryKnownToMan()
{
 return new Class;
}

// another class factory
Class * CreateClassWithLog()
{
   ClassWithLog * p = new ClassWithLog; // derived from Class
   p->SetLogFile("log.txt");
   return p;
}

// code consuming the class factory
void PopulateStars(createClassFunction * factory)
{
   // creates many instances of `Class` through `factory`
   Sky * sky = GetSky();
   for(int i=0; i<sky->GetStarCount(); ++i)
   {
      Class * inhabitant = (*factory)();
      sky->GetStar(i)->SetInhabitant(inhabitant);
   }
}

// code deciding which factory to use
const bool todayWeWriteALog = (rand() %2) != 0;
createClassFunction * todaysFactory = todayWeWriteALog ?
   &MostTrivialFactoryKnownToMan : 
   &CreateClassWithLog);

PopulateStars(factory);

__stdcall是一个编译器特定的属性,改变了调用约定(参数和返回值如何在调用者和实现之间传递)。这对于二进制兼容性通常很重要 - 例如当 Pascal 程序需要调用用 C 或 C++ 实现的函数时。

问题:

工厂函数返回一个原始指针。工厂和消费者之间必须有一个隐含的合同如何释放该指针(例如,通过delete 或示例)。 使用智能指针(例如 shared_ptr)作为返回类型将允许工厂确定删除策略。

工厂作为函数指针,可能不保存状态(比如日志文件名,需要在函数中硬编码,或者全局可用)。使用可调用对象将允许实现可配置工厂。

【讨论】:

    猜你喜欢
    • 2016-10-09
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    相关资源
    最近更新 更多