何时在C ++类中使用关键字“static”?

时间:2009-04-29 03:33:11

标签: c++ multithreading static

代码

 static void MyClass::ThreadEntryStatic()
 {
    //...
 }

 void MyClass::Begin()
 {
         CreateThread(..,ThreadEntryStatic,..);
 }

我们应该在哪种情况下使用类中的静态?

6 个答案:

答案 0 :(得分:4)

有三个地方可以使用关键字static。一个是在struct / class的声明中,当该上下文意味着该方法是一个类方法而不是一个实例方法。这意味着直接调用此方法,您不需要实例。从这个静态方法,您无法访问实例变量。

在MyClass.h中

struct MyClass
{
  static void ThreadEntryStatic();

  void Begin();
};

在MyClass.cpp中

void MyClass::ThreadEntryStatic()
{
}

void MyClass::Begin()
{
  CreateThread(.., MyClass::ThreadEntryStatic, ...);
}

使用static关键字的第二种情况是在文件的范围内,您不希望声明的变量的可见性在文件外可见。您也可以使用匿名命名空间。

使用static关键字的第三种情况是在方法的范围内,并且在函数的执行之间保留值(并在第一次使用赋值初始化)。

答案 1 :(得分:1)

如果您在多个线程上运行静态方法,则需要非常密切地关注同步代码。在我看来,在进行多线程编程时,我尝试在每个线程中使用我的对象或工作项的单独实例,并且完全避免使用任何类型的静态或共享数据。当然,这并不总是可行的,因此线程仍然是最棘手的编程领域之一。

答案 2 :(得分:1)

作为一个具体的例子,

class Test{
      static void foo();      
};

static void Test::foo(){
    // code here
}

不会编译,您无法在类声明之外声明带有static关键字的函数。您只需在实现该功能时删除static关键字。

class Test{
      static void foo();      
};

void Test::foo(){
    // code here
}

答案 3 :(得分:1)

有些人已经谈过这个问题,但是不应该使用用于内部链接的static,而应该使用匿名命名空间:

namespace
{

void myInternallyLinkedFunction()
{
    // do something
}

int myInternallyLinkedInteger;

class myInternallyLinkedClass
{
public:
    void doSomething();
};

} // anon namespace


void myExternallyLinkedFunction()
{

    ++myInternallyLinkedInteger;
    myInternallyLinkedFunction();
    myInternallyLinkedClass x;
    x.doSomething();
}

答案 4 :(得分:0)

在函数调用之间保留静态变量的值。检查this MSDN条目以获取示例。在chrish的回答中已经概述了定义和使用“静态”方法

静态可以在实现单例类时使用,其中您只需要一个类的实例。 它的用法取决于上下文。

答案 5 :(得分:0)

您的示例显示的是“静态成员函数线程回调”模式。由于线程函数必须具有WINAPI签名,因此它不能是普通的成员函数,只能是静态成员。通常将此作为线程参数传递给此回调,然后调用执行线程工作的真实成员。

只有一个静态成员的使用,并且有很多不同。很难猜出你问题的目的是什么。您是在解决某些特定问题,还是只对静态成员或静态成员函数的所有可能用途感兴趣?

“静态成员函数线程回调”的更完整示例:

class MyClass
{

  /// background rendering thread
  int ThreadEntry()
  {
     // do the work here
  }

  /// static member callback "proxy"
  static DWORD WINAPI ThreadEntryStatic(void *param)
  {
    return ((EngineDD9 *)param)->ThreadEntry();
  }

  void SpawnThread()
  {
    CreateThread(.., ThreadEntryStatic, ...);
  }

};