C++ 函数/方法设计的良好实践

alf*_*_80 1 c++ function

我对 C++ 函数/方法设计有如下困惑:

1.

class ArithmeticCalculation
{ 
private:
    float num1_;
    float num2_;
    float sum_;

    void addTwoNumbers();
};
Run Code Online (Sandbox Code Playgroud)

2.

class ArithmeticCalculation
{ 
private:
    float addTwoNumbers(float num1, float num2);
};
Run Code Online (Sandbox Code Playgroud)

在 1. 中,基本上可以声明一个类变量,而 void addTwoNumbers() 只会实现它并分配给类变量 ( sum_)。我发现使用 1. 更干净,但使用 2. 看起来对于函数使用更直观。

考虑到函数/方法不仅限于这个基本的加法功能,哪一个实际上是最佳选择——我的意思是一般来说如何决定使用 return 还是简单的 void?

das*_*ght 5

这两个函数之间的主要区别在于,第二个函数是无状态的*,而第一个函数有状态。在其他条件相同的情况下,无状态方法是首选,因为它为您的类的用户在他们的系统中使用您的类提供了更大的灵活性。例如,无状态函数是可重入的,而依赖状态的函数可能需要使用它们的代码采取额外措施来防止错误使用。

仅重入是尽可能选择无状态函数的一个重要原因。但是,在某些情况下,保持状态变得更加经济——例如,当您使用Builder Design Pattern 时

尽可能保持函数无状态的另一个重要优点是调用序列变得更具可读性。依赖状态的方法调用由以下部分组成:

  • 调用前设置对象
  • 打电话
  • 获取调用结果(可选)

与由三部分 setup-call-get 结果序列组成的三部分相比,您的代码的人类读者将更容易阅读使用带参数传递的函数调用的调用。

在某些情况下,您必须拥有状态,例如,当您想要推迟操作时。在这种情况下,参数由代码的一部分提供,而计算由代码的其他部分启动。就您的示例而言,一个函数将调用set_num1and set_num2,而另一个函数将addTwoNumbers在稍后调用。在这种情况下,您可以将参数保存在对象本身上,或者创建一个带有延迟参数的单独对象。

*这只是基于您的成员函数签名的假设。你的第二个函数获取它需要的所有数据作为参数,并将值返回给调用者;显然,实现可能会选择添加一些状态,例如通过保存最后的结果,但这对于addTwoNumbers函数来说并不常见,所以我假设您的代码不会这样做。

  • @alfa_80 理论上,需要复制从函数返回的向量,但允许 C++ 积极优化复制。例如,调用可以在调用者提供的空间中分配结果向量。在这种情况下,我会从最自然和可读的方法开始,只有在分析应用程序并确定返回一个大容器确实是一个主要瓶颈之后才进行修改。 (2认同)