好的,我已经了解了静态函数是什么,但是我仍然看不到为什么它们比私有成员函数更有用。这在这里可能是一个新奇的问题,但是为什么不只用静态函数代替所有私有成员函数呢?
static
限制功能的文件范围。
private member
我们的存在,我们可以放心地假设OP正在询问OO概念,并且不了解文件范围静态信息。
好的,我已经了解了静态函数是什么,但是我仍然看不到为什么它们比私有成员函数更有用。这在这里可能是一个新奇的问题,但是为什么不只用静态函数代替所有私有成员函数呢?
static
限制功能的文件范围。
private member
我们的存在,我们可以放心地假设OP正在询问OO概念,并且不了解文件范围静态信息。
Answers:
假设您使用的是OOP,则在不依赖任何类成员的情况下使用静态函数。它们仍然可以是私有的,但是由于不依赖于相关对象的任何实例,因此可以对它们进行优化。
除了上述内容之外,当您不想创建对象实例以仅在其上执行一个公共功能时,我发现静态函数很有用。对于包含公共功能的帮助程序类,主要是这种情况,它们可以执行一些重复性和常规性的工作,但是在调用之间不需要保持任何状态。
尝试提供比上述方法更简洁的解释(相当不错的解释)。
一个对象通常是代码+数据。当您只需要处理“代码”部分(没有数据/状态被维护(静态数据成员除外))时,将使用静态方法。
因为它们不需要实例并且可以是公共的。假设您需要一个函数来获取最大的公分母(GCD;对于分数类非常有用;是的,这只是一个简单的示例)。创建一类对象的唯一目的是可以拥有this
既不需要也不用的指针gcd
。因此,您可以为此使用静态方法,最好是在实际使用GCD的类上(例如,在分数类中)。
当然,如果只有静态方法,那么您将OOP做错了,应该切换到实际执行OOP或使用更适合您的范例的语言。
静态和私有实际上是正交的:一种方法可以是静态的,也可以是私有的,或者可以是无,或两者兼有。
静态与非静态(又称“实例方法”)表明方法是在类本身上运行(静态)还是在一个特定实例上运行(非静态)。根据语言的不同,您可以通过实例调用静态方法,但是永远不能通过静态方法访问实例(这也意味着您不能从静态方法内部调用任何非静态方法,这仅仅是因为您没有this
宾语)。使用静态方法来实现在概念上链接到该类但不“绑定”到一个特定实例的行为。您可能要使用静态方法的另一种情况是,当您有一个对一个类的两个实例进行操作的函数,而两个操作数都不应该享有特权状态时,例如,假设您有一个类Vector
,并且您想要实现加法;您的加法可以称为a.Add(b)
,但Vector.Add(a, b)
可能更有意义。
私有与公共是关于该方法的可见性。私有方法只能在类自己的范围内访问,而公共方法则可以在任何地方访问。最重要的用途是封装:通过仅公开其余代码与类进行通信所绝对需要的那些方法和属性,可以限制外部代码可能引入问题的点,并防止内部问题您的班级将精力投入到项目的其余部分。
因此,经验法则:
假设您正在谈论C ++(您未说),并且您拥有正确的术语(即,不表示成员函数/方法):
即使私有成员函数仍必须在标头中声明,这意味着它实际上已成为类的API和ABI的一部分,即使用户实际上无法调用它也是如此。如果添加,修改或删除私有成员函数,则将强制重新编译所有相关类(标头已更改,make可能无法更好地了解),并且在库中进行此操作时,必须考虑使用它。
另一方面,文件作用域的静态函数没有公共符号,因此您可以根据需要添加,修改或删除它们,并且一个编译单元之外的任何东西都不会受到影响。
可笑的是,没人能给出一个好的答案。我不确定这也是。您可能应该暗示它应该尽可能少地使用。他们毕竟是程序性的,而不是面向对象的。
这里还有更多示例:
在Obj-C中,它们被称为类方法,它们通常用作分配包装器,在该包装器中,对象在返回之前被放入引用计数池中。
Obj-C的另一个示例是将新类注册到类集合中。假设您有一组类,每个类都处理一种类型的文件。当为新文件类型创建新类时,可以使用确定文件类型的类中的静态方法将其注册到集合(全局变量)中。
在C ++中,我能想到的另一种用法是轻捕获错误。您的构造函数不会失败,除非抛出异常。您可以设置一个错误实例变量,但这并不总是合适的。相反,您可以执行可能在静态包装器中失败的部分,然后分配并返回新对象,如果失败,则返回NULL。
假设您要计算某物的正弦值。
没有静态:
Math math = new Math()
double y = math.sin(x)
带有静态:
double y = Math.sin(x)
使sin
非静态无意义。它是无状态的,仅处理输入。
静态函数不绑定到特定对象。它们是独立于对象内部状态的“一般”功能。
x.sin()
。您的答案假设罪应该是“算术”的函数,而罪恶显然是双重的。
有点晚了,但我想尝试创建一个精确的定义:静态函数是不包含引用或不能引用包含类的实例属性/方法的函数。
在某些语言中,例如C#,静态类中可能包含静态字段或属性,因此说它们不用于状态是不正确的。静态函数可能会利用静态(全局)状态。
从根本上讲,它可以归结为:静态函数,就像任何静态函数一样,在有意义的意义上总是可以使用而不依赖于非静态实例时很有用。
诸如数学函数之类的辅助函数是一个经常出现的示例,但是还有其他示例。
如果您创建的类要求数据是不可变的,则创建静态实例以接收实例并传递新实例可能是有意义的,因为不能(或不应)更改实例。例如,字符串类可能具有静态函数,这些函数接收一个字符串(或2个或更多)并传回新的字符串。
另一个原因可能是有一类保留全局状态或某种数据。可能有一些静态函数可以使用该静态类中的静态属性或字段。
我想指出静态f()的另一种用法。
http://www.parashift.com/c++-faq/named-ctor-idiom.html
归结为这一点:static
函数允许您创建“命名构造函数”,即您使用合适的且具有自文档说明的名称来命名静态函数,并且此静态函数调用其中一个构造函数(因为构造函数具有相同的名称,并且您可以使用其中很多,很难将它们区分开)。