为什么类中的线程函数必须要声明静态

其实类的静态函数就跟全局函数是一个样子的, 只是调用的时候要加下个类修饰符而已.

至于为什么不能是非静态成员函数呢, 因为非静态成员函数都会在参数列表中加上一个this指针为为参数, 这样的话你写的线程函数就不符合调用规定了.
比如 DWORD WINAPI ThreadFun(LPVOID); 是非静态的,实际编译后,就会变成
DWORD WINAPI ThreadFun(LPVOID, CMyClass *this);
这个函数就明显不能作为线程的函数了, 因为多了个参数.所以编译就过不了了.

参考地址:http://www.cnblogs.com/diegodu/p/4655036.html

它与设置成全局函数有一个好处:就是不用声明为friend成员即可访问对象的私有成员。

成员变量不用改成static的,你创建线程的时候把对象的“this”指针作为参数传递过去,就可访问了。

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

class Thread
{
    private:
        pthread_t pid;
    private:
        static void * start_thread(void *arg);// //静态成员函数
    public:
        int start();
        virtual void run() = 0; //基类中的虚函数要么实现,要么是纯虚函数(绝对不允许声明不实现,也不纯虚)
};

int Thread::start()
{
    if(pthread_create(&pid,NULL,start_thread,(void *)this) != 0) //′创建一个线程(必须是全局函数)
    {
        return -1;
    }
    return 0;
}

void* Thread::start_thread(void *arg) //静态成员函数只能访问静态变量或静态函数,通过传递this指针进行调用
{
    Thread *ptr = (Thread *)arg;
    ptr->run();  //线程的实体是run
}

class MyThread:public Thread
{
    public:
        void run();
};
void MyThread::run()
{
    printf("hello world\n");
}

int main(int argc,char *argv[])
{
    MyThread myThread;
    myThread.start();
    //test.run();
    sleep(1);
    return 0;
}

编译运行:

[email protected]:~/myProg/pthreadCpp$ g++ main.cpp -lpthread
[email protected]:~/myProg/pthreadCpp$ ./a.out
hello world
[email protected]:~/myProg/pthreadCpp$ 

参考地址:http://bbs.csdn.net/topics/280040692

有一个更加好的方法,就是使用boost::thread,结合boost::function,boost::bind很方便的实现类成员函数线程化

1.如何创建简单的线程

#include <boost/thread/thread.hpp>
#include <iostream>
using namespace std;

void helloworld()
{
    cout << "hello world" << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    boost::thread thd(&helloworld);
    thd.join();//等线程结束
}

2.如何给线程携带参数

#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
using namespace std;

void helloworld(string par1, int par2, double par3)
{
    cout << "hello world" << endl;
    cout << par1 << "," << par2 << "," << par3 << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    boost::thread thd(boost::bind(&helloworld,string("haha"),1,1.0));
    thd.join();//等线程结束
}

3.如何线程互斥

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
using namespace std;

boost::mutex mutex_;
int io_;
void thread_in()
{
    boost::mutex::scoped_lock lock(mutex_);
    cout << "in " << io_++ << endl;
}
void thread_out()
{
    boost::mutex::scoped_lock lock(mutex_);
    cout << "out " << io_-- << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
    boost::thread thd1(&thread_in);
    boost::thread thd2(&thread_out);
    thd1.join();
    thd2.join();
    io_ = 0;

}

4.如何让类成员函数线程化

#include <boost/thread/thread.hpp>
#include <string>
#include <iostream>
using namespace std;

class myclass
{
public:
    myclass():
      classname_("I am Hero")
    {

    }
protected:
    string classname_;
protected:
    void handle_thread()
    {
        cout << classname_ << endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    myclass c;
    boost::thread thd(boost::bind(&myclass::handle_thread,&c));
    thd.join();
}
时间: 2024-10-28 22:55:06

为什么类中的线程函数必须要声明静态的相关文章

在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static

在C++的类中,普通成员函数不能作为pthread_create的线程函数,如果要作为pthread_create中的线程函数,必须是static ! 在C语言中,我们使用pthread_create创建线程,线程函数是一个全局函数,所以在C++中,创建线程时,也应该使用一个全局函数.static定义的类的成员函数就是一个全局函数. 更多 参考  http://blog.csdn.net/ksn13/article/details/40538083 #include <pthread.h> #

检测某个方法是否属于某个类中--解析php函数method_exists()与is_callable()的区别

php函数method_exists() 与is_callable()的区别在哪?在php面相对象设计过程中,往往我们需要在调用某一个方法是否属于某一个类的时候做出判断,常用的方法有 method_exists()和is_callable() 相比之下,is_callable()函数要高级一些,它接受字符串变量形式的方法名作为 第一个参数,如果类方法存在并且可以调用,则返回true.如果要检测类中的方法是否能被调用,可以给函数传递一个数组而不是类的方法名作为参数.数组必须包含对象或类名,以将其作

在复数类中自定义类型转换函数实现复数和非复数之间的运算

实现复数+double型数据,并且打印运算后实部上的数据 #include <iostream> using namespace std; class Complex { public: Complex( )//定义默认构造函数初始化复数 { real=0; imag=0; } //使用初始化表初始化复数 Complex(double r, double i):real(r),imag(i){} //定义自定义类型转换函数 operator double() { return real; }

类中的回调函数

失败原因 由于类的成员函数有隐含的this指针传递,从而导致一个CALLBACK型的成员函数安装时函数参数个数不匹配. 解决方法 1)将回调函数挪出类外,并声明为友元 2)将回调函数生命为静态成员函数(使用回调函数的某个参数传递当前对象的this指针) 类中的回调函数,码迷,mamicode.com

c++ 类中模版成员函数

C++函数模版与类模版. template <class T> void SwapFunction(T &first, T &second){ }//函数模版 template <class T>//类模版 class CTemplate{ public: void SWap(T &first, T &second){ } }; #include <iostream> class Single{ public: static Single

Java继承类中static成员函数的重写

在java中,static成员函数是否可以被重写呢? 结论是,你可以在子类中重写一个static函数,但是这个函数并不能像正常的非static函数那样运行. 也就是说,虽然你可以定义一个重写函数,但是该函数没有多态特性.让我们测试一下: 1 class testClass1{ 2 static void SMothod(){ 3 System.out.println("static in testClass1"); 4 } 5 } 6 class testClass2 extends

类中含有虚函数的剖析

1. 源代码 #include <iostream> using namespace std; class Base { public : virtual void  FunTest() { cout << "Base::FunTest () " << this << endl; } virtual void  FunTest1() { cout << "Base::FunTest1 () " <&l

为什么在一个类中定义的函数默认是inline的

1.首先要说明的是一个inline函数具有静态链接(static linkage),不会被文件以外者看到. 2.编译是分模块进行的(不同的编译模块指不同的文件),使用#include把类的头文件包含进来,在预处理阶段会进行文本替换.如果此时在.h文件中定义了类的函数,那么包含了inlcude的文件在编译的时候就会把函数定义写入该编译模块目标文件中的.symtab符号表中.现在,如果.h类中的函数定义不是inline的话,.symtab中的函数符号符号便是向外公开的.如果多个文件中都include

python 类中的某个函数作为装饰器

在python的类中,制作一个装饰器的函数, class A: def wrapper(func): ###装饰器 def wrapped(self,*arg,**kwargs) ... return wrapped @ wrapper ###装饰mix def mix(): ... 当调用mix的时候,self.mix() ,会将self等参数传入 wrapper 中来吗?答案为否. 当wrapper作为装饰器的并且@wrapper这种方式作为装饰的时候,wrapper就跟普通的函数一样,仅仅