成员函数与非成员函数?

时间:2009-04-03 22:07:47

标签: c++ oop

对于在类上运行的函数应该是成员函数还是非成员函数,您的规则是什么? 例如,我有一个使用bools矩阵表示迷宫的类。我正在创建一个名为isConnected的函数,它验证迷宫中的2个点位于同一区域(即可以从A行进到B)。

这应该是会员还是非会员?什么是好规则?

6 个答案:

答案 0 :(得分:14)

Herb Sutter说:“如果合理可能的话,我们希望让他们成为非成员非朋友”,而且他比我更聪明。

http://www.gotw.ca/gotw/084.htm

答案 1 :(得分:13)

嗯,两者都存在争议。

赞成非成员函数:

  • 它提供better encapsulation
  • 它允许更好的代码重用(std :: find可以重用于任何容器类型,因为它是一个自由函数。如果它是一个成员,那么容器必须定义它自己的)
  • 它使很多通用编程技巧变得更容易。如果container.begin()是一个数组,则container无效。这使得编写处理容器的通用代码变得更加尴尬。但begin(container)可以对任何类型都有效,甚至可以构建 - 像数组一样)。它还可以通过合成使mixins更加清晰,因为它不需要用户通过成员“点”自己来获取你想要操作的mixin对象。

赞成制作会员功能的是:

  • 很熟悉。 Java和C#需要这一点,在很多程序员看来,成员函数都是OOP的同义词。

并且......就是这样。 (但是这个论点不应该被低估。代码可读性很重要,如果人们发现阅读成员版本更容易,那么这是一个有利的论据。它只是不会产生更好的代码。从严格的“更好的代码”从这个角度来看,应尽可能优先选择非成员。

答案 2 :(得分:11)

何时使其成为会员功能:

  • 当函数与类逻辑耦合时(如迷宫连接示例)
  • 当函数需要访问私有或受保护的成员时,最好将其作为成员而不是朋友。

何时使其成为独立功能

  • 当它是一个通用函数,可以被模板化以自然地在其他类上工作(请查看< algorithms>标题以获得良好示例)

答案 3 :(得分:4)

在这种情况下,我会选择会员功能。 我遵循的规则是,如果函数必须访问实例当前状态内部的东西,那么它应该是类的“领域”的一部分。 在这种情况下,A和B的连通性取决于对象实例的状态。

当然,你最终可能会有一个职责太多的课程。在这种情况下,保持简单的因素开始,你应该考虑你的班级是否试图做太多。这样就可以很方便地拥有一个独立的类(例如,在你的情况下,一个ConnectednessEvaluator),其特定的作用是保存可以遍历并作用于你的Maze实例的算法。

答案 4 :(得分:3)

我总是回顾FAQ 13.9。这不是一门精确的科学,而是一种基于自由裁量权的科学。

当你需要访问类内部时,你应该使用一个成员,这是一种过于简单化的说法。值得注意的例子是流插入/提取运算符(分别为>><<)和二进制+

在您的示例中,isConnected是一种测试对象状态的方法,即检查员和成为成员的理想候选人。

答案 5 :(得分:0)

我倾向于制作非成员函数的唯一东西是只从成员函数中调用的东西(不需要在类外部可见),并且可以在类的公共成员上正常运行和/或少量参数。