静态函数有什么用处?

发布于 2024-10-08 17:55:46 字数 73 浏览 0 评论 0原文

我不明白所有这些关键字。特别是这个static。如果有一个例子来说明它的重要性以及它如何使用,那就太好了。

I don't get all these keywords. Specially this one static. An example of how important it is and how it used would be wonderful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

生来就爱笑 2024-10-15 17:55:46

将成员函数设置为static 允许您在不创建类对象的情况下调用该函数。

class MyClass
{
    int i;
    static MyClass *ptr;
    static MyClass* getInstance()
    {
        if(NULL == ptr)  
        {
            ptr = new MyClass();
        }
        return ptr;
    }

};

MyClass* MyClass::ptr = NULL;

int main()
{
    MyClass *ptr = MyClass::getInstance();

}

查看单例模式以了解有关它如何提供帮助的更多信息。

Making a member function static allows you to call the function without creating the class object.

class MyClass
{
    int i;
    static MyClass *ptr;
    static MyClass* getInstance()
    {
        if(NULL == ptr)  
        {
            ptr = new MyClass();
        }
        return ptr;
    }

};

MyClass* MyClass::ptr = NULL;

int main()
{
    MyClass *ptr = MyClass::getInstance();

}

Check out the Singleton pattern for more information on how it can be helpful.

冷了相思 2024-10-15 17:55:46

静态成员函数就像常规函数一样。

class Sample
{
    public:
        static void DoWork() 
        {
           cout << "Static Member Function"<< endl;
        }
};

//access
Sample::DoWork();

输出:

静态成员函数

您可以像常规函数一样对待它们,这意味着您可以将它们传递给仅接受常规函数作为参数的其他函数,如下所示:

typedef void (*Worker)();
void Fun(Worker worker)
{
    //call here just like regular function
    worker(); //note: class name is not needed even if you pass static member function!
}

//pass static member function!!
Fun(Sample::DoWork);

输出:

静态成员函数

static member functions are just like regular functions.

class Sample
{
    public:
        static void DoWork() 
        {
           cout << "Static Member Function"<< endl;
        }
};

//access
Sample::DoWork();

Output:

Static Member Function

You can treat them just like regular functions, that means, you can pass them to other functions which accept only regular function as argument, like this:

typedef void (*Worker)();
void Fun(Worker worker)
{
    //call here just like regular function
    worker(); //note: class name is not needed even if you pass static member function!
}

//pass static member function!!
Fun(Sample::DoWork);

Output:

Static Member Function

‖放下 2024-10-15 17:55:46

static 关键字有多种用途,根据您使用它的位置,它会执行不同的操作。

http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx

当你声明一个变量或者
文件范围内的函数(全局和/或
命名空间范围),static 关键字
指定变量或
功能具有内部联系。什么时候
你声明一个变量,变量
具有静态持续时间和编译器
除非您指定,否则将其初始化为 0
另一个值。

当你在a中声明一个变量时
函数中,static关键字指定
变量保留其状态
对该函数的调用之间。

当您在
类声明,static 关键字
指定该成员的一份副本
由所有实例共享
班级。静态数据成员必须是
在文件范围内定义。积分
您声明为 const 的数据成员
static 可以有一个初始值设定项。

当你声明一个成员函数时
类声明,静态
关键字指定该函数是
由该类的所有实例共享。
静态成员函数无法访问
实例成员,因为
函数没有隐式
这个指针。访问实例
成员,用 a 声明该函数
参数是实例指针
或参考。

There are multiple uses for the static keyword, it does different things based on where you use it.

http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx

When you declare a variable or
function at file scope (global and/or
namespace scope), the static keyword
specifies that the variable or
function has internal linkage. When
you declare a variable, the variable
has static duration and the compiler
initializes it to 0 unless you specify
another value.

When you declare a variable in a
function, the static keyword specifies
that the variable retains its state
between calls to that function.

When you declare a data member in a
class declaration, the static keyword
specifies that one copy of the member
is shared by all instances of the
class. A static data member must be
defined at file scope. An integral
data member that you declare as const
static can have an initializer.

When you declare a member function in
a class declaration, the static
keyword specifies that the function is
shared by all instances of the class.
A static member function cannot access
an instance member because the
function does not have an implicit
this pointer. To access an instance
member, declare the function with a
parameter that is an instance pointer
or reference.

怎樣才叫好 2024-10-15 17:55:46

静态类和类成员用于创建无需创建类实例即可访问的数据和函数。优点是不需要实例化类即可使用方法或属性。

何时使用静态类的一个示例可能是实用程序函数,例如转换器(例如华氏温度到摄氏温度)。无论任何对象或数据如何,这种类型的函数都不会改变。

在 C# 中,您可以像这样调用静态方法:

double F, C = 0

// TempConverter converter = new TempConverter();  <-- NOT NEEDED FOR STATIC

F = TempConverter.CelsiusToFahrenheit("100.0");

C = TempConverter.FahrenheitToCelcius("212.0");

以下是静态类和方法的定义方式:

public static class TemperatureConverter {

  public static double CelsiusToFahrenheit(string temperatureCelsius) {
    .. conversion code..
  }
  public static double FahrenheitToCelsius(string temperatureFahrenheit)  {
    .. conversion code..
  }
}

Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. The advantage is that you don't need to instantiate the class to use methods or properties.

An example of when to use a static class might be for utility functions such as converters (e.g. Fahrenheit to Celcius). This type function doesn't change irregardless of any object or data.

In C# you can call a static method like this:

double F, C = 0

// TempConverter converter = new TempConverter();  <-- NOT NEEDED FOR STATIC

F = TempConverter.CelsiusToFahrenheit("100.0");

C = TempConverter.FahrenheitToCelcius("212.0");

Here is how the static class and methods are defined:

public static class TemperatureConverter {

  public static double CelsiusToFahrenheit(string temperatureCelsius) {
    .. conversion code..
  }
  public static double FahrenheitToCelsius(string temperatureFahrenheit)  {
    .. conversion code..
  }
}
冷了相思 2024-10-15 17:55:46

静态函数有两种类型:类/结构成员和非成员。我猜你想知道前者(因为它更令人困惑)...

静态成员函数

如果我们对比四个函数:

class X
{
    ....
    int non_static_member_f(X& a) { ... }
    static int static_member_f(X& a) { ... }
    friend int non_member_friend_f(X& a) { ... }
};

int non_member_f(X& a) { ... }

并给出:

X x, arg; 

我们可以写:

  • x.non_static_member_f (arg) - x 是现有的 X 对象实例 - 可通过 this 指针进行访问。该函数可以完全访问所有private/protected/public static/non-staticX 的 code> 成员,用于对 xarg 进行操作。

  • X::static_member_f(arg) 可以使用单个 X 参数调用 - 如果函数未指定 X 参数,那么可以在没有现有 X 对象的情况下调用它。它可以完全访问 X 的所有 private/protected/public static,并且可以访问 arg 上的任何非static 成员。

  • non_member_friend_f(arg)X::static_member_f(arg) 具有相同的访问权限,但不在 X 内部(即您不需要使用 X:: 前缀调用它,Koenig 查找的解析方式不同)。

  • non_member_f(arg)只能访问arg的public成员,没有特殊权限。


为了完整性:静态非成员函数与非静态函数的不同之处在于具有内部链接,这意味着它们不能从其他翻译单元调用,但不会与这些翻译单元中的任何同名函数发生冲突。

There are two types of static functions: class/struct member, and non-member. I guess you're wondering about the former (as it's more confusing)...

static member functions

If we contrast four functions:

class X
{
    ....
    int non_static_member_f(X& a) { ... }
    static int static_member_f(X& a) { ... }
    friend int non_member_friend_f(X& a) { ... }
};

int non_member_f(X& a) { ... }

And given:

X x, arg; 

We can write:

  • x.non_static_member_f(arg) - x is an existing X object instance - made accessible via the this pointer. The function has full access to all private/protected/public static/non-static members of X for operations on x and arg.

  • X::static_member_f(arg) can be invoked with a single X argument - if the function didn't specify an X argument, then it could be called with no existing X objects. It has full access to all private/protected/public static of X, and can access any non-static members on arg.

  • non_member_friend_f(arg) has the same access as X::static_member_f(arg), but is not scoped inside X (i.e. you don't need to call it with the X:: prefix, Koenig lookup resolves differently).

  • non_member_f(arg) can only access the public members of arg, and has no special privileges.


For completeness: static non-member functions differ from non-static in having internal linkage, which means they're not callable from other translation units but won't clash with any same-named function in those translation units.

心房的律动 2024-10-15 17:55:46

静态函数在实现所谓的命名构造函数时非常有用。

想象一个 Point 类,它可以从直角坐标(X/Y)或极坐标(半径和角度)构造:

class Point {
public:
  Point(float x, float y);     // Rectangular coordinates
  Point(float r, float a);     // Polar coordinates (radius and angle)
  // ERROR: Overload is Ambiguous: Point::Point(float,float)
};

int main()
{
  Point p = Point(5.7, 1.2);   // Ambiguous: Which coordinate system?
  ...
}

使用创建 Point 的静态函数可以很好地解决这个问题代码>对象;这些函数被称为命名构造函数,因为它们的行为类似于构造函数(它们生成一个新对象),但它们可以有一个描述性名称:

class Point {
public:
  // These static methods are the so-called "named constructors"
  static Point rectangular(float x, float y) { return Point(x, y); }
  static Point polar(float radius, float angle) { return Point(radius*std::cos(angle), radius*std::sin(angle)); }

  // ...
private:
  Point(float x, float y) : x_(x), y_(y) { }
  float x_, y_;
};

类的客户端现在可以使用这些命名构造函数来创建可读的、明确的代码:

int main()
{
  Point p1 = Point::rectangular(5.7, 1.2);   // Obviously rectangular
  Point p2 = Point::polar(5.7, 1.2);         // Obviously polar
}

此外,命名构造函数可用于确保类的对象始终分配有new(以便您知道您始终可以对它们调用delete)。有关详细信息,请参阅常见问题解答 [16.21]

Static functions are very useful when implementing so-called Named Constructors.

Imagine a Point class which can be either constructed from rectangular coordinates (X/Y) or polar coordinates (radius and angle):

class Point {
public:
  Point(float x, float y);     // Rectangular coordinates
  Point(float r, float a);     // Polar coordinates (radius and angle)
  // ERROR: Overload is Ambiguous: Point::Point(float,float)
};

int main()
{
  Point p = Point(5.7, 1.2);   // Ambiguous: Which coordinate system?
  ...
}

This can be solved very nicely using static functions which create Point objects; such functions are called named constructors since they act like a constructor (they produce a new object) but they can have a descriptive name:

class Point {
public:
  // These static methods are the so-called "named constructors"
  static Point rectangular(float x, float y) { return Point(x, y); }
  static Point polar(float radius, float angle) { return Point(radius*std::cos(angle), radius*std::sin(angle)); }

  // ...
private:
  Point(float x, float y) : x_(x), y_(y) { }
  float x_, y_;
};

Clients of the class can now use these named constructors to create readable, unambiguous code:

int main()
{
  Point p1 = Point::rectangular(5.7, 1.2);   // Obviously rectangular
  Point p2 = Point::polar(5.7, 1.2);         // Obviously polar
}

Furthremore, named constructors can be used to make sure that objects of a class are always allocated with new (so that you know that you can always call delete on them). See FAQ [16.21] for more information.

﹂绝世的画 2024-10-15 17:55:46

静态类成员函数很有用:

  1. 用于实现工厂方法模式
  2. 用于实现单例模式
  3. 用于可能破坏类行为的函数的松散解耦。 (函数不一定可以声明为静态成员......但更好的是,它们可以是完全经典的函数!) cf SRP
  4. 可以用作函数,作为普通 C 函数指针传递,以便与 C 代码进行互操作...

静态函数很有用:
1.避免编译时重复代码重定义。将为包含其中的每个 cpp 单元重新定义一个静态函数。

而且我认为现在还有大量其他有用的情况我不记得了:-)

static class member functions are useful:

  1. For implementing the Factory Method Pattern
  2. For implementing the Singleton Pattern
  3. For loose decoupling of functions that may polute the behaviour of the class. ( Functions not necessarily members can be declared static... but even better they could be totally classic functions!) cf S.R.P.
  4. Can be used as a function to be passed as a plain C function pointer so as to inter-operate with C code...

static functions are useful:
1. to avoid duplicate code redefinition while compiling. A static function will be redefined for each cpp unit it is included in.

And I think there are tons of other useful cases I don't remember of right now :-)

惯饮孤独 2024-10-15 17:55:46

martona 的答案很好地概述了 静态。关于静态成员,我认为 Tony 很好地涵盖了它。

当涉及到成员函数时,我使用的心理模型是考虑如何在“C”中对它们进行建模:

class A
{
public:
  void mbr_1 ();
  void mbr_2 () const;
  void mbr_3 () volatile;
  void mbr_4 () const volatile;
  static void mbr_5 ();
};

可能实现为:

struct A { };
void mbr_1 (A * const this);
void mbr_2 (A const * const this);
void mbr_3 (A volatile * const this);
void mbr_4 (A const volatile * const this);
void mbr_5 ();

所有函数都是成员,因此对私有成员具有适当的“访问权”。非静态成员有一个“this”指针,它提供对特定实例成员的访问。静态成员没有这样的指针,这就是为什么我们无法访问任何非静态成员。

The answer from martona is a good overview of static. Relating to static members, I think Tony covers it pretty well.

The mental model I use when it comes to member functions is to consider how they might be modeled in 'C':

class A
{
public:
  void mbr_1 ();
  void mbr_2 () const;
  void mbr_3 () volatile;
  void mbr_4 () const volatile;
  static void mbr_5 ();
};

Might be implemented as:

struct A { };
void mbr_1 (A * const this);
void mbr_2 (A const * const this);
void mbr_3 (A volatile * const this);
void mbr_4 (A const volatile * const this);
void mbr_5 ();

All the funcitons are members and so have appropriate 'access' to private members. The non static members have a 'this' pointer, and it is that which provides the access to a specific instances members. The static member doesn't have such a pointer and this is why we cannot access any non static members.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文