您是否将创建一个私有类成员来消除多级函数调用

Will you create a private class member to eliminate multi-level function call?

本文关键字:成员 函数调用 多级 一个 创建 是否      更新时间:2023-10-16

虽然我在C++写了这个例子,但这个代码重构问题也适用于任何支持OO的语言,比如Java。

基本上我有一个A类

class A
{
public:
  void f1();
  void f2();
  //..
private:
  m_a;
};
void A::f1()
{
  assert(m_a);
  m_a->h1()->h2()->GetData();
  //..
}
void A::f2()
{
  assert(m_a);
  m_a->h1()->h2()->GetData();
  //..
}

你们会m_f持有指针m_a->h1()->h2()创建一个新的私有数据成员吗?我可以看到的好处是,它有效地消除了多级函数调用,这确实大大简化了代码。

但从另一个角度来看,它创建了一个"不必要的"数据成员,可以从另一个现有的数据成员m_a中推断出来,这有点多余?

我只是在这里陷入困境。到目前为止,我无法说服自己使用一个而不是另一个。

你们更喜欢哪个,有什么原因吗?

这种技术的奇特词是缓存:你计算一次两个离开的引用,并将其缓存在对象中。通常,缓存允许您使用计算机内存"付费"以加快计算速度。

如果探查器告诉您代码在重复调用m_a->h1()->h2()中花费了大量时间,则这可能是合法的优化,前提是 h1h2 的返回值永远不会更改。但是,在没有先分析的情况下进行这样的优化几乎总是过早优化的坏兆头。

如果性能不是问题,一个好的规则是远离存储可以从对象中存储的其他成员计算的成员。如果你想提高清晰度,你可以引入一个命名良好的方法(成员函数)来计算二离引用,而无需存储它。只有在对性能至关重要的极少数情况下,存储才有意义。

我不会。我同意这只是你人为的例子中的事情,但那是因为m_a->h1()->h2()没有内在的意义。在设计良好的应用程序中,使用的方法名称应该告诉您有关所进行调用的一些定性信息,这应该是自记录代码的一部分。我认为,在正确设计的代码中,m_a->h1()->h2()应该比重定向到为您调用它的私有方法更容易阅读和理解

现在,如果m_a->h1()->h2()是一个昂贵的调用,需要花费大量时间来计算结果,那么您可能会按照@dasblinkenlight的建议进行缓存。但是,为了几次按键而丢弃方法调用的描述性是不好的。

每当我有这样的东西时,我通常会将 m_a->h1() 存储到一个在函数范围内具有有意义名称的变量中,因为它可能会稍后在函数的主体中再次使用。