繁体   English   中英

静态成员函数

[英]Static member functions

在阅读sbi和Eli Bendersky在这个问题中的答案后,我开始想知道静态成员函数的用途。

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

一般来说:

要求访问私人会员

静态成员函数可以访问该类的私有成员。 如果需要,可以使用静态成员函数。 你必须在标题中声明它才能让它访问,所以你也可以把它变成一个成员而不是一个朋友。 对于具有getInstance()方法作为单例的单例,以及使用静态工厂方法createInstance()来确保它们在堆上创建的类,通常采用这种方式。 这两个都需要访问私有构造函数。

元编程

静态成员函数非常适合模板元编程,在这种情况下,您可以传入一个类并调用其方法,而无需在调用时知道实际调用哪个函数。 这通常称为“编译时多态”,是元编程的重要组成部分。 std :: char_traits基于这个原则。

禁止进入

私有静态成员函数的常见用法,只是为了使它只能由类访问,并且本身不需要访问私有成员,不能很好地利用静态成员函数,因为它是实现细节的一部分。这个类,最好在编译单元的匿名命名空间中完成。

但是,如果静态成员函数受到保护 ,则可以使用它,因为它可以由派生类调用,但不能由外部类调用。

朋友的功能

  • 可以访问私有成员,但无论如何都需要在标题中声明。
  • 可以在元编程中用作“重载”的一部分,但仍需要在标头中声明。 (常见的例子是operator<<
  • 对于友好的受保护访问不起作用,因为您在此处尝试执行的操作是限制对方法的访问,而不是访问该访问权限的访问权限。

静态方法:

  • 在类创建的“命名空间”中提供封装。 如果您的类是Animal并且静态方法是Create ,则必须使用Animal::Create调用它。 这比全局函数更好,并允许使用相对自然的语法实现工厂和“虚拟构造函数”。
  • 可以访问静态成员。 这些成员在某些情况下很有用,如果没有静态方法和成员,则必须使用全局变量和函数。

通常,坦率地说,你不应该这样做。 免费功能被大大低估了。

使用静态成员获得的隐式“命名空间”(假装该类只不过是静态成员的命名空间,这是真的)是我能想到的唯一好处。

如果静态函数成员需要持久变量,那么将静态数据成员与其一起使用的能力也可能有用。

有些人对使用静态函数持谨慎态度,因为它经常被那些来自程序背景并且不理解OO的人使用。

但是,有许多设计模式使用静态成员函数实现是有意义的

例如。 单例和工厂模式命名为我的头脑,实际上大多数需要创建对象的结构模式都需要静态成员函数。

正确识别后, static成员函数没有任何附加值。 更糟糕的是,当用于实现细节时,这会引入额外的依赖性(在编译方面)。

无法使用匿名自由函数模拟的唯一用途是protected访问,即访问父静态函数的派生类。 但是,这绝不是必需的:您可以将其设为常规成员函数(我假设您没有全局状态,否则静态/朋友区别不是直接关注的)。

已经引发了模板元编程中static函数的使用......但是它与内部类型问题非常相似:它使得提供默认版本变得困难。 另一方面,适当定义的自由函数(将类型作为指针)可以提出模板版本:

struct some_traits
{
  static void doStuff();
};

// versus

struct some_traits {};

void doStuff(some_traits*);

// and the default: void doStuff(...);

当然,当成员函数为用户提供更多灵活性时,总会有这样一个问题:为什么这应该是一个静态函数。 为此,我将引用标准委员会使用Allocator概念所做的步骤:现在授权有状态分配器,这使我们有机会在同一页面中打包给定map的节点,而不是将它们分布在整个堆中。

最后,还有界面问题。 然而,自从Sutter提倡一个类和在同一个头中定义的自由函数都构成了这个类的公共接口=>这是ADL的用途以来已经很久了! 因此,对于古代的OO程序员而言,它比“良好实践”更能让人感到舒服。

真的,我认为使用static成员函数没有任何好处。 我想人们会认为相反提出真实案例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM