假设我有,或者将要写,一组相关的函数。假设它们与数学有关。在组织方面,我应该:
编写这些函数,并将它们放在我的MyMath命名空间中,并通过MyMath::XYZ()引用它们 创建一个名为MyMath的类,并使这些方法是静态的,并引用类似的MyMath::XYZ()
为什么我要选择其中一种来组织我的软件呢?
假设我有,或者将要写,一组相关的函数。假设它们与数学有关。在组织方面,我应该:
编写这些函数,并将它们放在我的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的最初动机)
其他回答
如果需要静态数据,请使用静态方法。 如果它们是模板函数,并且您希望能够为所有函数一起指定一组模板形参,那么可以在模板类中使用静态方法。
否则,请使用命名空间函数。
对于这些评论:是的,静态方法和静态数据往往被过度使用。这就是为什么我只提供了两个相关的场景,我认为它们会有所帮助。在OP的特定示例(一组数学例程)中,如果他想要指定参数的能力——例如,核心数据类型和输出精度——将应用于所有例程,他可能会这样做:
template<typename T, int decimalPlaces>
class MyMath
{
// routines operate on datatype T, preserving at least decimalPlaces precision
};
// math routines for manufacturing calculations
typedef MyMath<double, 4> CAMMath;
// math routines for on-screen displays
typedef MyMath<float, 2> PreviewMath;
如果您不需要这样做,那么无论如何都要使用名称空间。
我想总结并补充其他答案。此外,我的视角是只看头部的世界。
名称空间
优点:
命名层次结构的简单解决方案 它们没有语义,所以读起来更简单 可以存在于不同的文件中(头文件) 可以扩展 诽谤联盟 可以定义快捷方式(使用)。 很好地与操作符过载 可以用于品牌(你可以设计你的代码并在上面放置一个名称空间)
缺点:
一切都是公开的 私有的东西需要未命名的命名空间,所以它不是显式的 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::