在this question阅读sbi和Eli Bendersky的答案之后,我开始想知道静态成员函数的用途。
一个类'朋友免费功能应该不能做任何静态成员函数可以做什么?如果是这样,为什么/何时我应该更喜欢静态成员函数给朋友免费?
答案 0 :(得分:12)
一般来说:
要求访问私人会员
静态成员函数可以访问该类的私有成员。如果需要,可以使用静态成员函数。你必须在标题中声明它才能让它访问,所以你也可以把它变成一个成员而不是一个朋友。对于具有getInstance()方法作为单例的单例,以及使用静态工厂方法createInstance()来确保它们在堆上创建的类,通常采用这种方式。这两个都需要访问私有构造函数。
<强>元编程强>
静态成员函数非常适合模板元编程,在这种情况下,您可以传入一个类并调用其方法,而无需在调用时知道实际调用哪个函数。这通常称为“编译时多态”,是元编程的重要组成部分。 std :: char_traits基于这个原则。
限制访问
私有静态成员函数的常见用法,只是为了使它只能由类访问,并且本身不需要访问私有成员,不能很好地利用静态成员函数,因为它是该类的实现细节,最好在编译单元的匿名命名空间中完成。
但是,如果静态成员函数是受保护的,则它可以使用,因为它可以被派生类调用,但不能被外部类调用。
朋友的功能
operator<<
)答案 1 :(得分:11)
静态方法:
Animal
且静态方法为Create
,则必须使用Animal::Create
进行调用。这比全局函数更好,并允许使用相对自然的语法实现工厂和“虚拟构造函数”。答案 2 :(得分:4)
坦率地说,你不应该这样做。免费功能大大评价不足。
使用静态成员获得的隐式“命名空间”(假装该类只不过是静态成员的命名空间,这是真的)是我能想到的唯一好处。
如果静态函数成员需要持久变量,那么拥有静态数据成员的能力也可能有用。
答案 3 :(得分:3)
有些人对使用静态函数持谨慎态度,因为它经常被那些来自程序背景并且不理解OO的人使用。
然而,有许多设计模式使用静态成员函数实现是有意义的
例如。单例和工厂模式命名为我的头脑,实际上大多数需要创建对象的结构模式都需要静态成员函数。
答案 4 :(得分:1)
正确识别后,static
成员函数没有附加价值。更糟糕的是,当用于实现细节时,这会引入额外的依赖关系(在编译方面)。
仅使用无法使用匿名自由函数进行模拟的是protected
访问,即访问父静态函数的派生类。但是,这绝不是必需的:你可以把它变成一个普通的成员函数(我假设你没有全局状态,否则静态/朋友的区别不是直接关注的。)
在模板元编程中使用static
函数已被引发......但它与内部类型问题非常相似:它使得提供默认版本变得困难。另一方面,适当定义的自由函数(将类型作为指针)可以提出模板版本:
struct some_traits
{
static void doStuff();
};
// versus
struct some_traits {};
void doStuff(some_traits*);
// and the default: void doStuff(...);
当然,当成员函数为用户提供更多灵活性时,总会存在为什么这应该是静态函数的问题。为此,我想引用标准委员会用Allocator
概念所做的举动:现在授权有状态分配器,这使我们有机会在同一页面中打包给定map
的节点而不是将它们传播到整个堆中。
最后,还有 interface 问题。然而,自从Sutter提倡在同一标题中定义的类和自由函数都构成此类的公共接口时,已经很长时间了。这就是ADL的用途!因此,对于古代的OO程序员而言,这比“良好实践”更令人感到安慰。
真的,我认为使用static
成员函数没有任何好处。我希望人们会相反提出真实案例。