使用基于策略的设计,一个EncapsulatedAlgorithm
:
template< typename Policy>
class EncapsulatedAlgorithm : public Policy
{
double x = 0;
public:
using Policy::subCalculate;
void calculate()
{
Policy::subCalculate(x);
}
protected:
~EncapsulatedAlgorithm() = default;
};
可能有一个执行子计算的 策略
。这个子计算对于算法来说不是必要的:它只是在某些情况下用于加速算法收敛。因此,为了模拟这种情况,假设有三种策略。
其中一种只是“记录”一些东西:
struct log
{
static void subCalculate(double& x)
{
std::cout << "Doing the calculation" << endl;
}
};
计算机:
struct calculate
{
static void subCalculate(double& x)
{
x = x * x;
}
};
有一个将它们聚集在一起并将它们束缚在黑暗中的人:D - 这完全没有任何作用:
struct doNothing
{
static void subCalculate(double& x)
{
// Do nothing.
}
};
这是示例程序:
typedef EncapsulatedAlgorithm<doNothing> nothingDone;
typedef EncapsulatedAlgorithm<calculate> calculationDone;
typedef EncapsulatedAlgorithm<loggedCalculation> calculationLogged;
int main(int argc, const char *argv[])
{
nothingDone n;
n.calculate();
calculationDone c;
c.calculate();
calculationLogged l;
l.calculate();
return 0;
}
这里有一个实时的例子(点击跳转)。我试着检查带优化的gcc
生成的汇编代码:
g++ -S -O3 -std=c++11 main.cpp
但我对汇编语言不够了解,无法确定结果的解释-生成的文件很小,我无法识别函数调用,因为所有策略的静态函数的代码都是内联的。
我能看到的是,在没有针对主函数进行优化的情况下,在主函数中存在一个与“doNothing :: subCalculate”相关的call
和随后的leave
。
call _ZN9doNothing12subCalculateERd
leave
以下是我的问题:
- 我应该从何处开始学习才能够读懂
g++ -S
的输出? - 空函数是否被优化掉了?在
main.s
中的哪些行中可以看到? - 这个设计是否可行?通常来说,实现一个什么都不做的函数是一件坏事,因为接口所表达的意思完全不同于实际情况(例如,
subCalculate
而不是doNothing
),但是对于策略模式来说,策略名称清楚地表明该函数不会执行任何操作。否则,我需要进行类型特征处理,例如使用enable_if
等,只是为了排除一个单独的函数调用。
iostream
以获得最小的输出。如果我这样做并使用 -O3 编译示例且没有调试信息,它就变成了return 0
:即xorl %eax, %eax
,该语句只是通过将 eax 寄存器与自身异或来将 eax 寄存器设置为0
。 - pmr-fdump-tree-all
生成中间 Gimple dumps ...(它会输出数百个文件,但其中一些非常易读,具有类似 C 的语法)。另请参阅 MELT。 - Basile Starynkevitch