2009-04-29 34 views
0

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

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

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

在这种条件下,我们应该使用静态类?

+2

这是一个线程相关的问题或C++的问题? – Tom 2009-04-29 03:37:48

+3

这个问题的标题是误导性的。增加与线程有关的事情可能会澄清事情。 – 2009-04-29 03:53:20

回答

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

1

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

0

函数调用之间保留静态变量的值。示例请查询this MSDN条目。在chrish的回答中已经列出了定义和使用“静态”方法的方法

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

1

举一个具体的例子,

class Test{ 
     static void foo();  
}; 

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

不会编译,你是不是能够声明与static关键字的函数类的声明之外。在实现该功能时,您只需删除静态关键字。

class Test{ 
     static void foo();  
}; 

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

有几个人谈到了这一点,但用于内部连接static不应该被使用,而应该使用匿名的命名空间:

namespace 
{ 

void myInternallyLinkedFunction() 
{ 
    // do something 
} 

int myInternallyLinkedInteger; 

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

} // anon namespace 


void myExternallyLinkedFunction() 
{ 

    ++myInternallyLinkedInteger; 
    myInternallyLinkedFunction(); 
    myInternallyLinkedClass x; 
    x.doSomething(); 
} 
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, ...); 
    } 

};