VC6中,为什么只有类中的static成员函数,才可

系统 1553 0

VC6中,为什么只有类中的static成员函数,才可以做为线程启动函数(ThreadProc)?

类中的static成员函数,存放在堆区吧?
类中的非静态成员函数,也存放在堆区吧?

如果是,那么为什么会出现如题的现象呢?

回复内容
【an_bachelor】:
个人以为应该都放在代码段

【haoranisme】:
堆区就存在代码段吧?

那么,为什么只有类中的static成员函数,才可以做为线程启动函数(ThreadProc)呢?

【laolaoliu2002】:
static是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从static修饰符的产生原因、作用谈起,全面分析static修饰符的实质。

static的两大作用:

一、控制存储方式:

  static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间。

  1、引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题:如果想将函数中此变量的值保存至下一次调用时,如何实现?
最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

  2、解决方案:因此c++中引入了static,用它来修饰变量,它能够指示编译器将此变量在程序的静态存储区分配空间保存,这样即实现了目的,又使得此变量的存取范围不变。

二、控制可见性与连接类型:

  static还有一个作用,它会把变量的可见范围限制在编译单元中,使它成为一个内部连接,这时,它的反义词为”extern”.

  static作用分析总结:static总是使得变量或对象的存储形式变成静态存储,连接方式变成内部连接,对于局部变量(已经是内部连接了),它仅改变其存储方式;对于全局变量(已经是静态存储了),它仅改变其连接类型。

类中的static成员:

一、出现原因及作用:

  1、需要在一个类的各个对象间交互,即需要一个数据对象为整个类而非某个对象服务。

  2、同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

  类的static成员满足了上述的要求,因为它具有如下特征:有独立的存储区,属于整个类。

二、注意:

  1、对于静态的数据成员,连接器会保证它拥有一个单一的外部定义。静态数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。

  2、类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致了它仅能访问类的静态数据和静态成员函数。


【laolaoliu2002】:
将成员函数声明为静态虽然可以解决作为线程函数的问题,但是它带来了新的问题,那就是static成员函数只能访问static成员。解决此问题的一种途径是可以在调用类静态成员函数(线程函数)时将this指针作为参数传入,并在改线程函数中用强制类型转换将this转换成指向该类的指针,通过该指针访问非静态成员。

【haoranisme】:
学习了,但还是想知道:

为什么只有类中的static成员函数,才可以做为线程启动函数(ThreadProc),
而类的非静态成员函数不可以?



【gaooo】:
成员函数调用需this

【gaooo】:
非成员函数不需要this指针

【haoranisme】:
突然想到,会不会是为了区分代码段和数据段呢?

【robinwjb】:
线程函数是独立于类的实例而存在的,他的生命期不是类的生命期,而是整个process。
试想一下,如果可以用非静态成员函数作为线程函数,如果没有定义一个这个类的实例,
岂不是无法调用线程函数了?


【haoranisme】:
试想一下,如果可以用非静态成员函数作为线程函数,如果没有定义一个这个类的实例,
岂不是无法调用线程函数了?


++++++++++++++++++++++++++++++++++++++++++++++++++++
不明白呀!

【LiChenYue】:
学习!关注!

【robinwjb】:
试想一下,如果可以用非静态成员函数作为线程函数,如果没有定义一个这个类的实例,
岂不是无法调用线程函数了?


++++++++++++++++++++++++++++++++++++++++++++++++++++
不明白呀!

------------------------------------------------------------
静态成员(无论是函数还是变量)是存储在全局变量区的,也就是在整个程序生命中有效的。
而非静态成员是随类的实例生成而生,随着类的实例死亡而死的。
所以,如果非静态成员函数作为线程函数的话,此时这个类的实例不存在,而程序要生成线程了,却发现线程函数根本不存在。

【haoranisme】:
非静态成员函数,也存储全局变量区(堆区)吧?

【chehw】:
设某函数原型为LRESULTThreadProc(LPVOIDpv);

若为非静态成员函数,编译时自动展开为ThreadProc(pClass->this,pv);与线程函数调用不相符。所以必须使用全局函数或类静态成员函数

【haoranisme】:
会不会是为了区分代码段和数据段呢?


【robinwjb】:
非静态成员函数,也存储全局变量区(堆区)吧?

------------------------------------------------

如果没有类的实例,则非静态成员函数没有存储空间。
只是作为代码存在代码区

【wltg2001】:
成员函数都有一个隐含参数this,也就是指向这个对象实例的指针,所以不能做启动函数

【wltg2001】:
用成员函数作线程启动函数编译应该都不会过,就是因为参数不匹配的原因

【haoranisme】:
感觉不象

【kouzhongling】:
设某函数原型为LRESULTThreadProc(LPVOIDpv);

若为非静态成员函数,编译时自动展开为ThreadProc(pClass->this,pv);与线程函数调用不相符。所以必须使用全局函数或类静态成员函数

---------------------------------------------
同意

作为线程入口当然不应该与类对象共存亡应该具有全局性
俺认为所有方法均在于代码段至于堆中是否存有可执行代码我也想知道
我一直认为堆只是存放数据的地方

【haoranisme】:
谢谢各位了!

【Nowish】:
mark~

VC6中,为什么只有类中的static成员函数,才可以做为线程启动函数(ThreadProc)?


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论