【问题标题】:When to use the keyword "static" in C++class?何时在 C++ 类中使用关键字“static”?
【发布时间】:2009-04-29 03:33:10
【问题描述】:

代码

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

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

在什么情况下我们应该在类中使用静态?

【问题讨论】:

  • 这是线程相关问题还是 c++ 问题?
  • 这个问题的标题具有误导性。添加与线程有关的内容可能会澄清一些事情。
  • 线程重要吗?用户显然不理解静态函数的概念。线程库需要使用静态函数这一事实大概是突出问题的原因......

标签: c++ multithreading static


【解决方案1】:

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

在 MyClass.h 中

struct MyClass
{
  static void ThreadEntryStatic();

  void Begin();
};

在 MyClass.cpp 中

void MyClass::ThreadEntryStatic()
{
}

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 这不是静态方法的问题,而是静态数据成员的问题。并且所有的类方法,包括非静态的,都可以访问它们。
    【解决方案3】:

    作为一个具体的例子,

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

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

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

    【讨论】:

      【解决方案4】:

      一些人已经谈到了这一点,但不应使用用于内部链接的static,而应使用匿名命名空间:

      namespace
      {
      
      void myInternallyLinkedFunction()
      {
          // do something
      }
      
      int myInternallyLinkedInteger;
      
      class myInternallyLinkedClass
      {
      public:
          void doSomething();
      };
      
      } // anon namespace
      
      
      void myExternallyLinkedFunction()
      {
      
          ++myInternallyLinkedInteger;
          myInternallyLinkedFunction();
          myInternallyLinkedClass x;
          x.doSomething();
      }
      

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          您的示例显示的是“静态成员函数线程回调”模式。由于线程函数必须有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, ...);
            }
          
          };
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-23
            • 1970-01-01
            • 2010-12-18
            相关资源
            最近更新 更多