假设我有,或者将要写,一组相关的函数。假设它们与数学有关。在组织方面,我应该:
编写这些函数,并将它们放在我的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的最初动机)
其他回答
你应该使用命名空间,因为命名空间比类有很多优点:
您不必在同一个头文件中定义所有内容 您不需要在头文件中公开所有实现 你不能使用类成员;可以使用名称空间成员 不能使用类,尽管使用名称空间通常不是一个好主意 使用类意味着在实际上没有对象时创建某个对象
在我看来,静态成员被过度使用了。在大多数情况下,它们并不是真正必要的。静态成员函数可能更适合作为文件作用域函数,而静态数据成员只是全局对象,只是有一个更好的、不应有的声誉。
我想总结并补充其他答案。此外,我的视角是只看头部的世界。
名称空间
优点:
命名层次结构的简单解决方案 它们没有语义,所以读起来更简单 可以存在于不同的文件中(头文件) 可以扩展 诽谤联盟 可以定义快捷方式(使用)。 很好地与操作符过载 可以用于品牌(你可以设计你的代码并在上面放置一个名称空间)
缺点:
一切都是公开的 私有的东西需要未命名的命名空间,所以它不是显式的 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的最初动机)
为什么我要选择其中一种来组织我的软件呢?
如果您使用名称空间,您将经常遇到一个语言缺陷,即相互调用的函数必须以特定的顺序列出,因为c++无法在文件中看到进一步的定义。
如果使用类,则不会出现此缺陷。
在类中包装实现函数比维护所有实现函数的声明或以非自然的顺序放置实现函数以使其易于编译更简单。
命名空间和类方法都有各自的用途。命名空间有能力分布在文件中,但如果你需要强制所有相关的代码进入一个文件,这是一个弱点。如上所述,类还允许您在类中创建私有静态成员。你可以把它放在实现文件的匿名命名空间中,但是它的作用域仍然比在类中更大。
我更喜欢名称空间,这样可以在实现文件中的匿名名称空间中拥有私有数据(因此与私有成员相反,它根本不必显示在头文件中)。另一个好处是,通过使用命名空间,方法的客户端可以选择不指定MyMath::