假设我有,或者将要写,一组相关的函数。假设它们与数学有关。在组织方面,我应该:

编写这些函数,并将它们放在我的MyMath命名空间中,并通过MyMath::XYZ()引用它们 创建一个名为MyMath的类,并使这些方法是静态的,并引用类似的MyMath::XYZ()

为什么我要选择其中一种来组织我的软件呢?


当前回答

命名空间和类方法都有各自的用途。命名空间有能力分布在文件中,但如果你需要强制所有相关的代码进入一个文件,这是一个弱点。如上所述,类还允许您在类中创建私有静态成员。你可以把它放在实现文件的匿名命名空间中,但是它的作用域仍然比在类中更大。

其他回答

我想总结并补充其他答案。此外,我的视角是只看头部的世界。


名称空间

优点:

命名层次结构的简单解决方案 它们没有语义,所以读起来更简单 可以存在于不同的文件中(头文件) 可以扩展 诽谤联盟 可以定义快捷方式(使用)。 很好地与操作符过载 可以用于品牌(你可以设计你的代码并在上面放置一个名称空间)

缺点:

一切都是公开的 私有的东西需要未命名的命名空间,所以它不是显式的 ADL(是的,有些人鄙视ADL) 可以扩展(这可能是一件坏事,特别是与ADL结合使用时,扩展名称空间会改变现有代码的语义) 函数需要按使用顺序定义(或声明)


具有静态方法的类

优点:

can have private components (function, variables) and they are explicitly marked. classes can be friended can be type-parametrized (templates) can be template parameters themselves can be instantiated can be passed to functions (static functions behave like non-static method by default). it is easier to find patterns and go from groups of independent functions and convert them to a proper class (eventually with non static members) dependencies among classes is well defined functions (the static method) can be defined in any order

缺点:

没有诽谤联盟 不能扩展 到处都需要关键字static(取笑语言的机会) 单独解决命名问题有点过头了。在这种情况下很难阅读。 函数(静态方法)总是需要限定(myclassspace::fun)。没有办法声明快捷方式(使用)。 几乎无用的操作过载,需要复杂的朋友机制。 不能用于打品牌。 你要记得以;:)

总而言之,带有静态方法的类是更好的代码单元,允许更多的元编程,除了ADL和一些语法怪才之外,它们可以复制名称空间的所有功能,但有时它们可能会过度使用。

像Bloomberg这样的公司更喜欢类而不是名称空间。 如果你不喜欢ADL或操作符重载,带静态方法的类是最好的选择。

在我看来,如果将命名空间和类集成成同一枚硬币的两面,那就太好了。 例如,如果方法默认是静态的,则将语言中的命名空间标识为类。 然后能够将它们作为模板参数使用。 我不确定用ADL做什么(可能它可以被限制为符号运算符函数,例如operatorX,这是运算符重载和ADL的最初动机)

命名空间和类方法都有各自的用途。命名空间有能力分布在文件中,但如果你需要强制所有相关的代码进入一个文件,这是一个弱点。如上所述,类还允许您在类中创建私有静态成员。你可以把它放在实现文件的匿名命名空间中,但是它的作用域仍然比在类中更大。

有很多人不同意我的观点,但我是这样看的:

类本质上是某种对象的定义。静态方法应该定义与该对象定义密切相关的操作。

如果你只是要有一组相关的函数,而不与底层对象或一种对象的定义相关联,那么我会说只使用名称空间。对我来说,从概念上讲,这更合理。

例如,在你的情况下,问自己,“MyMath是什么?”如果MyMath没有定义一种对象,那么我会说:不要让它成为类。

但就像我说的,我知道有很多人(甚至激烈地)不同意我的观点(特别是Java和c#开发人员)。

使用类-选项的另一个原因是使用访问说明符。然后,您可以将公共静态方法分解为更小的私有方法。公共方法可以调用多个私有方法。

我更喜欢名称空间,这样可以在实现文件中的匿名名称空间中拥有私有数据(因此与私有成员相反,它根本不必显示在头文件中)。另一个好处是,通过使用命名空间,方法的客户端可以选择不指定MyMath::