我没有得到所有这些关键字。特别是这一个static
。它的重要性和使用方式的一个例子很棒。
答案 0 :(得分:2)
阅读this以获得澄清。
答案 1 :(得分:2)
创建成员函数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();
}
查看Singleton pattern
,了解有关如何提供帮助的更多信息。
答案 2 :(得分:1)
static关键字有多种用途,它会根据您使用它的位置执行不同的操作。
http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx
声明变量或 在文件范围内的功能(全局和/或 命名空间范围),静态关键字 指定变量或 功能有内部联系。什么时候 你声明一个变量,即变量 有静态持续时间和编译器 除非您指定,否则将其初始化为0 另一个值。
在a中声明变量时 function,static关键字指定 变量保持其状态 在调用该函数之间。
在a中声明数据成员时 类声明,静态关键字 指定该成员的一个副本 由所有实例共享 类。必须是静态数据成员 在文件范围定义。一个完整的 您声明为const的数据成员 static可以有一个初始化器。
在中声明成员函数时 一个类声明,静态 keyword指定函数是 由所有类实例共享。 静态成员函数无法访问 一个实例成员,因为 函数没有隐含 这个指针。访问实例 成员,用a声明函数 参数是一个实例指针 或参考。
答案 3 :(得分:1)
静态类和类成员用于创建可在不创建类实例的情况下访问的数据和函数。优点是您不需要实例化类以使用方法或属性。
何时使用静态类的示例可能是实用程序功能,例如转换器(例如Fahrenheit到Celcius)。无论任何对象或数据如何,此类型函数都不会更改。
在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..
}
}
答案 4 :(得分:1)
static 成员函数就像常规函数一样。
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);
输出:
静态成员函数
答案 5 :(得分:1)
有两种类型的静态函数:class / struct member和non-member。我想你对前者感到疑惑(因为它更令人困惑)......
静态成员函数
如果我们对比四个函数:
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
static
/非X
成员,以便{{1} }和x
。
arg
参数调用 X::static_member_f(arg)
- 如果函数未指定X
参数,则可以调用它而不存在{{1}对象。它可以完全访问X
的所有X
/ private
/ protected
public
,并且可以访问static
上的所有非X
成员1}}。
static
与arg
具有相同的访问权限,但不在non_member_friend_f(arg)
范围内(即您无需使用X::static_member_f(arg)
前缀调用它,Koenig查找解析不同)。
X
只能访问arg的X::
成员,并且没有特殊权限。
为了完整性:静态非成员函数与具有内部链接的非静态函数不同,这意味着它们不能从其他翻译单元调用,但不会与这些翻译单元中的任何同名函数冲突。
答案 6 :(得分:1)
在实现所谓的Named Constructors时,静态函数非常有用。
想象一个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
个对象的静态函数可以非常好地解决这个问题。这些函数称为named constructors
,因为它们的作用类似于构造函数(它们生成一个新对象),但它们可以具有描述性名称:
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)。有关详细信息,请参阅FAQ [16.21]。
答案 7 :(得分:0)
静态类成员函数很有用:
静态函数很有用: 1.编译时避免重复代码重新定义。将为包含在其中的每个cpp单元重新定义静态函数。
我认为现在还有很多我不记得的有用案例: - )
答案 8 :(得分:0)
martona的答案是对static
的一个很好的概述。关于静态成员,我认为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'指针,它是提供对特定实例成员的访问的指针。静态成员没有这样的指针,这就是我们无法访问任何非静态成员的原因。