1

目前,我一直在阅读“ Apache Thrift ”的源代码。更具体地说,用C++实现的代码,放在这个路径:“thrift-0.9.1.tar\thrift-0.9.1\lib\ cp”。

我一直想知道为什么“TProtocol 类”是这样设计的:

我们知道“TProtocol Class”是一个抽象类。而且这里有详细的分析:“ developermemo ”。并且说“还定义了相应的抽象工厂类,用于生产具体的协议对象,这是最常用的设计模式抽象工厂设计模式。”

但是,我想知道为什么他们定义一个函数对应的纯虚函数被调用。例如:

  virtual uint32_t writeSetEnd_virt() = 0;
  virtual uint32_t writeBool_virt(const bool value) = 0;  //Pure virtual function

  uint32_t writeBool(const bool value) {                  //
  T_VIRTUAL_CALL(); 
  return writeBool_virt(value);                           //call the "interface"
  }

为什么我们需要“writeBool()”。好像没什么用。为什么我们不直接定义“纯虚函数”和“派生类”重写这些接口。

4

2 回答 2

2

可以看出...writeBool不仅仅是调用writeBool_virt. 它还执行,它跟踪调试构建中的执行T_VIRTUAL_CALL();

仅使用虚函数是不可能创建这种行为的,因为您不能保证每个派生类都会正确调用T_VIRTUAL_CALL();.

虚拟调用正在做尽可能少的工作(它们只是提供一个点来自定义 的行为TProtocol),并且不构成外部公共接口的一部分。这减少了组件之间的耦合,并使实现TProtocol更加私有。

于 2014-05-29T07:06:48.883 回答
2

这是一种称为“模板方法”的模式。您经常拥有一个公共的、非虚拟的函数和一个私有的、虚拟的函数的组合。除了转发之外,公共的还做一些事情,比如检查前置条件和后置条件、日志记录和简单的转换。私人的、虚拟的做实际的工作。将其设为私有的理由是要明确表明您没有选择调用基本版本的选择权,否则您可以通过显式derived.base::foo()调用来执行此操作。如果您需要扩展基本版本,您也可以将其设置为受保护,但这里不是这种情况。

于 2014-05-29T07:18:19.317 回答