静态成员函数

时间:2011-01-18 10:45:01

标签: c++ function static static-members non-member-functions

this question阅读sbi和Eli Bendersky的答案之后,我开始想知道静态成员函数的用途。

一个类'朋友免费功能应该不能做任何静态成员函数可以做什么?如果是这样,为什么/何时我应该更喜欢静态成员函数给朋友免费?

5 个答案:

答案 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成员函数没有任何好处。我希望人们会相反提出真实案例。