每当我有一些“实用”方向的功能时,我最终都会想知道哪个选项是最好的。例如,在我正在工作的上下文中打印消息结构(自己的或外部的)、一些编码/解码代码或一些有用的转换函数。
我想到的选项是:
1) 辅助类/结构中的静态函数。
struct helper
{
static bool doSomething(...);
};
2)非成员函数。
namespace helper
{
bool doSomething(...);
}
3) 静态非成员函数。
namespace helper
{
static bool doSomething(...);
}
在某些情况下,可能需要在“实用程序”中初始化或保留状态,因此我选择选项 1 以避免“全局”状态。但是,如果没有需要保留的状态,那么我应该选择选项2还是选项3呢?选项 2 和选项 3 之间有什么实际区别?
What is 重要的是要考虑有没有一个首选方式接近这个?谢谢!
选项 2 和 3 之间的区别在于,在第二种情况下,该函数将位于翻译单元内部。如果该函数仅在 cpp 中定义,则这应该是选项(大致相当于未命名的命名空间——这是要考虑的第四个选项,同样大致相当于 3)。
如果该函数要被不同的翻译单元使用,那么您应该选择选项 2。该函数将被编译一次(除非您将其标记为inline
并在标头中提供定义),而使用选项 3 时,编译器将在每个翻译单元中创建它的内部副本。
至于选项1,我会避免它。在 Java 或 C# 中,你被迫到处使用类,最终会得到实用程序类当操作不能很好地映射到对象范例时。另一方面,在 C++ 中,您可以将这些操作作为独立函数提供,并且无需添加额外的层。如果您选择实用类,不要忘记禁用对象的创建。
函数是否位于类级别或命名空间级别都会影响查找,从而影响用户代码。静态成员函数始终需要使用类名进行限定,除非您位于类作用域内,而将命名空间函数引入作用域有不同的方法。作为说明性示例,考虑一堆数学辅助函数和调用代码:
double do_maths( double x ) {
using namespace math;
return my_sqrt( x ) * cube_root(x);
}
// alternatively with an utility class:
double do_maths( double x ) {
return math::my_sqrt(x) * math::cube_root(x);
}
您认为哪一个更容易阅读是另一回事,但我更喜欢前者:在函数中,我可以选择名称空间,然后只关注操作并忽略查找问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)