首页 \ 问答 \ C ++函数/方法设计的良好实践(Good practice in C++ function/method design)

C ++函数/方法设计的良好实践(Good practice in C++ function/method design)

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

1。

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

    void addTwoNumbers();
};

2。

class ArithmeticCalculation
{ 
private:
    float addTwoNumbers(float num1, float num2);
};

在1.中,基本上可以声明一个类变量,而void addTwoNumbers()将实现它并分配给类变量( sum_ )。 我发现使用1.更清洁,但使用2.看起来更直观的功能使用。

考虑到函数/方法,哪一个实际上是最好的选择并不仅限于这个基本的附加功能 - 我的意思是如何决定如何使用return或者仅仅是void?


I have a confusion about C++ function/method design as below:

1.

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

    void addTwoNumbers();
};

2.

class ArithmeticCalculation
{ 
private:
    float addTwoNumbers(float num1, float num2);
};

In 1., one can basically declare a class variable and the void addTwoNumbers() will just implement it and assign to the class variable (sum_). I found using 1. is cleaner but using 2. looks like it more intuitive for function use.

Which one is actually best option considering the function/method is not restricted to only this basic addition functionality -- I mean in general how to decide to use with return or simply void?


原文:https://stackoverflow.com/questions/47420381
更新时间:2019-07-15 05:16

最满意答案

这两个函数的主要区别在于第二个函数是无状态* ,而第一个函数有一个状态。 在其他条件相同的情况下,无状态方法更受欢迎,因为它可以让您班级的用户在系统中利用您的班级时更加灵活。 例如,无状态函数是可重入的,而依赖于状态的函数可能需要使用它们的代码采取额外措施来防止错误使用。

只要可能,重新进入就是选择无状态函数的一个重要原因。 但是,在保持状态变得更经济的情况下 - 例如,当您使用Builder Design Pattern时

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

  • 在通话之前设置对象
  • 拨打电话
  • 收获通话结果(可选)

您的代码的人类阅读者读取使用带有参数传递的函数调用的调用比读取三部分的调用 - 获取结果序列更容易。

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

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


The major difference between the two functions is that the second one is stateless*, while the first one has a state. Other things being equal, stateless approach is preferred, because it gives the users of your class more flexibility at utilizing your class in their systems. For example, stateless functions are re-entrant, while functions that rely on state may require the code that uses them to take additional measures that prevent incorrect use.

Re-entrancy alone is a big reason to prefer stateless functions whenever possible. However, there are situations when keeping state becomes more economical - for example, when you are using Builder Design Pattern.

Another important advantage of keeping your functions stateless whenever it is possible is that the call sequence becomes more readable. A call of a method that relies on the state consists of these parts:

  • Set up the object before the call
  • Make the call
  • Harvest the result of the call (optional)

Human readers of your code will have much easier time reading the call that uses a function invocation with parameter passing than the three-part setup-call-get result sequence.

There are situations when you have to have state, for example, when you want to defer the action. In this case the parameters are supplied by one part of the code, while the computation is initiated by some other part of the code. In terms of your example, one function would call set_num1 and set_num2, while another function would call addTwoNumbers at some later time. In situations like this you could save the parameters on the object itself, or create a separate object with deferred parameters.

* This is only an assumption based on the signature of your member function. Your second function gets all the data that it needs as parameters, and returns the value to the caller; Obviously, implementations may choose to add some state, e.g. by saving the last result, but that is uncommon for addTwoNumbers functions, so I assume that your code does not do it.

2017-11-21

相关问答

更多

C / C ++(其他语言太?)有条件的早期返回良好的代码实践(C/C++ (Other Languages Too?) Conditional Early Return Good Code Practice)

如果else子句很短,那么else只会增加清晰度,最多只需几行代码。 如果您想要检查几个初始条件,则源很快就会混乱。 我唯一一次使用else,如果它是一个带有小的else的小函数,意味着少于大约10个源行,并且没有其他初始检查。 在某些情况下,我使用了一个循环,以便一系列初始检查可以使用中断离开。 do { ... } while (0); 我不愿意使用goto,这实际上保证至少有一个真正的信徒可以减少编程。 这将取决于您组织的任何代码标准。 我倾向于喜欢极简主义,所以我使用你提供的第一个版 ...

电脑二级当中的VB\VF\C\C++专题讲座|这些内容详细内容

VB 是Visual Basic编程语言 编写计算机程序需要使用计算机编程语言。计算机编程语言是人和计算机“对话”的桥梁。就像人类的语言一样,计算机编程语言也有很多。目前较为广泛使用的语言有“C++”、“Pascal”、“Basic”等。在众多的计算机编程语言中,以BASIC语言最为易学易用。 BASIC是英文Beginner’s All purpose Symbolic Instruction Code的缩写,意思为初学者通用符号指令代码,一直都是程序设计入门的首选语言。 1991年,Visu

具有更多参数的C#子类方法中的OOP设计(OOP Design in C# subclass method with more parameters)

不完全确定你想要实现的目标,但你可能想重新考虑设计。 似乎min/max/extra值不应传递给Calculate方法,而是设置为属性或在构造函数中传递。 public class Threshold { public int Min { get; set; } public int Max { get; set; } public virtual int Calculate( int input ) { // logic goes here ...

C ++ Singleton设计模式(C++ Singleton design pattern)

看到这篇文章为一个简单的设计懒惰评估与保证破坏单身人士: 任何人可以在C ++中为我提供Singleton的样本? 经典的懒惰评估并正确地破坏了单身人士。 class S { public: static S& getInstance() { static S instance; // Guaranteed to be destroyed. // Instant ...

C#矩阵类设计(转置方法)(C# matrix-class design (transpose method))

我宁愿投票支持 public Matrix Transpose() { ... } 可能性1 是的,恕我直言,可疑,因为Matrix似乎是不可变的 (所有其他方法都不会改变它)。 此外,其他操作(如果你决定实现它们),例如算术+, - ,*,/, 也不改变初始矩阵,它们会返回一个新的矩阵。 Matrix B = -A; // <- A doesn't changed Matrix D = A + B * C; // <- A, B, C don't changed Matr ...

自学C++有前途吗

C++自学的话非常难,因为c++需要学习的东西很多而且很难,如果你没掌握学习c++的方法的话,可能1-2年都只能入门,如果你掌握c++的学习的方法的话,半年就能学会C++。 …………………………………… 看你问的问题,应该是对c++很感兴趣,其实你可以自学c++。关于如何学习c++,我刚才看到一篇很不错的文章,是一个专科生介绍自己如何自学c++,并找到c++的工作,里面介绍了他的学习方法和学习过程,希望对你有帮助。 先做个自我介绍,我07年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名

c++ 设计模式策略模式 design pattern strategy

COMP实际上就是你说的策略。指定COMP为std:less 就可以了,前提是你的 迭代器支持这个标注类型

使用C ++的原理和实践,如何退出循环(principles and practice using C++, how to exit a loop)

完成输入字符串后,按Enter键 ,然后按Ctrl + Z(如果在Windows上)或Ctrl + D(如果在Linux上),然后再按Enter键 。 这会将EOF字符发送到输入流,导致cin >> temp; 条件到(隐式)求值为false从而退出for循环 。 以上可以转换为使用while循环: #include <iostream> #include <vector> #include <string> int main() { char c = 'y'; std::str ...

相关文章

更多

最新问答

更多
  • Unity着色器错误;(Unity shader error; presumably in if statement)
  • 如何在Liferay portlet中设置Cookie?(How to set a Cookie in Liferay portlet?)
  • C#只读访问List <>或其他集合,或ToArray()魔术(C# readonly access to List<> or other collection, or ToArray() magic)
  • 如何使用Google Web工具包创建登录应用程序?(How to create a login application using Google web tool kit? [closed])
  • 如何使我的函数返回结果作为全局变量?(How to make my function return results as a global variable?)
  • 为什么我的网站需要“启用32位应用程序”?(Why does my website need “Enable 32-bit applications”?)
  • 红宝石数组具有相同的值(ruby array of hash with same value)
  • Android(在Scala中):StackOverflowError取决于何时启动线程?(Android (in Scala): StackOverflowError depends on when to start a thread?)
  • 适用于iOS应用的通用链接(Universal Links for iOS apps)
  • 创建并打开文件linux编程(create and open file linux programming)
  • Datepicker,第2个日期是从第1个日期开始的X天(Datepicker, 2nd date is X days from 1st date)
  • 背景大小过渡不起作用(Transition on background-size doesn't work)
  • 在React / Redux中的On Click函数中传递Prop(Passing a Prop in an On Click Function in React/Redux)
  • 关键字在代码中做了什么,是否有没有此关键字的替代方法?(what does the keyword this does in the code and are there any alternate methods without this keyword? [duplicate])
  • 反向设计FoxPro / dBsae数据库以创建EER模型(Reverse Engineer a FoxPro/dBsae database to create the EER model)
  • 在R中的变量中组合具有相同值的行(Combine rows that have same value in a variable in R [duplicate])
  • SQL Server:非空唯一主键(SQL Server: Non-null unique vs. Primary Key)
  • 将扩展ASCII字符代码转换为ISO-8859-1(Convert extended ASCII character codes to ISO-8859-1)
  • 如何在.NET中读取m4a文件中的标签?(How to read tags out of m4a files in .NET?)
  • 呼叫链接的性能提升?(Performance gain on call chaining?)
  • 风景名胜区规划设计文本里面都包含哪些内容?推荐一家旅游规划设计公司?谢谢!
  • 如何在String中将字符串转换为枚举?(How do I convert a string to enum in TypeScript?)
  • SQLite SELECT出现异常如何解决它?(SQLite SELECT gives exception How to fix it?)
  • NSLog不会从ViewController类输出,而是来自AppDelegate类的WILL。(NSLog will NOT output from the ViewController class, but WILL from the AppDelegate class. iOS:Objective C)
  • 更改UIPicker突出显示的标签宽度(change UIPicker highlighted tab width)
  • 空心倒五角形(Hollow inverted pentagon)
  • 如何设置仅使用OpenID的Plone站点(How to setup Plone sites working only with OpenID)
  • Paperclip缺少Amazon S3的协议(https)(Paperclip is missing the Protocol (https) with Amazon S3)
  • 从宏中部署netbeans中的ANT文件(Deploy ANT file in netbeans from macro)
  • XMLReader是未知的(XMLReader is unknown)