动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ C/C++教程 ]的信息

本月文章推荐
.确定一个应用程序是否没有响应.
../configure make make install分.
.C++数据结构学习:二叉树(2).
.C语言教程第一章: C语言概论.
.C程序开发经典实例之8.
.CIH v1.2源程序.
.Delphi 插件创建、调试与使用应用.
.两个截取字符串的实用方法(超过.
.C++箴言:让=返回一个*this的引用.
.教你理解复杂的C/C++声明.
.一个模拟lc 的数字显示控制台程序.
.在CB环境中实现在菜单中显示历史.
.C++习题与解析(重载-02).
.罗云彬VxD教程--虚拟设备驱动程序.
.数据结构学习(C++)之图.
.C/C++编程新手错误分析(1).
..
.C++/CLI中实现singleton模式.
.全国计算机等级考试二、三、四级.
.VC下显示JPEG、GIF图像的简便方法.

在单独线程中执行对象成员函数

发表日期:2008-3-8 |


问题的提出:

  实际上所有线程都是用来处理C函数的,而不是C++类成员函数。标准库中提供一个API函数,这个函数以回调函数指针作为线程的执行代码并在单独的线程中调用回调函数。问题是在这样的线程库中不能创建执行对象成员函数的线程;只能使用普通的函数。因此,下列代码是失败的:

// 启动线程库函数的线程
int thr_create (void (*pf)(), void* prm, thread_t* pth); #include "class1.h" int func (void *param )
{
thread_t t1;
// 下列调用导致编译器错误: "Cannot convert ''void (class1::*)()'' to ''void (*)()''"
// 意思是不能转换类型
return thr_create ( &class1::some_method, param, &t1);
}   函数thr_create()需要回调函数的地址,void* 作为地址参数被传递到回调函数,同时传递的参数还有thread_t变量的指针(有关回调函数和函数指针的概念参见VC知识库中另外的文章)。   上面的代码之所以编译失败是因为传递到thr_create()的第一个参数是类class1的成员函数指针,而不是普通函数指针。从概念上讲,普通函数和类成员函数是两个完全不同的事情。即使进行强制类型转换也不行。那么如何解决这个问题呢?   方法一:使用静态成员函数   第一个解决方法是使回调成员函数为静态。因为静态成员函数不带隐含式参数“this”。因此,可以将其参数中的地址当作是普通函数的指针来使用。假如要从静态成员函数中访问对象的数据成员,显式传入对象的地址即可。例如: class Hack
{
private:
int x;
public:
int get_x();
static void func(Hack * pthis); // 静态成员函数
void func2(); // 非静态成员函数
}; void Hack::func(Hack * pthis)
{
int y = pthis->get_x(); // 访问对象的数据成员
}   这个方法在大多数情形下都能行得通,但有时候成员函数不能声明为静态,也就是说成员函数是虚函数或者正在使用不能修改的第三方类。碰到这种情况时,用方法一解决问题就比较难了。   方法二:处理非静态成员函数   假设需要在单独的线程中调用类Hack的非静态成员函数func2()。不用直接传递成员函数的地址到thr_create(),声明一个带 void* 参数的普通函数intermediary(void*),然后调用它: void intermediary(void*);   接着创建一个结构,结构定义如下: strUCt A
{
Hack * p; //类对象指针
void (Hack::*pmf)(); // 成员函数指针
};   创建一个结构实例,用希望的对象地址和成员函数地址填充结构(有关具体的成员函数指针内容请参见VC知识库中的其它文章)。 A a; // 结构实例
Hack h; // 创建对象
//填充结构
a.p = & h;
a.pmf = &Hack::func2; // 取成员函数地址   现在回过头来实现intermediary()函数: void intermediary(void* ptr)
{
 A* pa=static_cast < A* > (ptr); // 强制转换 p 为 A*
 Hack* ph=pa->p; // 从A中析取Hack对象地址
 void (Hack::*pmf)()=pa->pmf; // 析取 ptr 到成员函数
 (ph->*pmf)(); // 调用成员函数
}   最后将intermediary()的地址传递到thr_create(): thr_create (intermediary, (void*) &a, &t1 );   thr_create()调用函数intermediary()并将A的地址传递给它。intermediary()再从其指针参数中展开结构A并调用希望的成员函数。这种间接方式的处理可以安全地在单独线程中启动成员函数,即便是线程库不支持成员函数。假如需要调用不同类的不同成员函数,可以将结构A转换成类模板,将函数intermediary()转换成函数模板。从而编译器便会自动产生大多数样板文件代码。
上一篇:BCB及Delphi工程文件扩展名一览 人气:348
下一篇:让TRichEdit支持BIG5内码 人气:285
浏览全部C/C++的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-8-21 Nucleus v3.33 多国语言版
2008-8-21 HDWiki v4.0 bulid 080821 UTF-8
2008-8-21 明科在线客服系统 v6.0
2008-8-21 KesionCMS v5.0.2 正式版 utf-8
2008-8-21 KesionEshop v5.0.2 正式版 utf-8
2008-8-21 HDWiki v4.0 bulid 080821 GBK
2008-8-21 新文互动酷站展示系统 v1.5
2008-8-21 Punbb v1.2.20 多国语言版
2008-8-21 QQ头像网 beta
2008-8-16 iLaba Player(小喇叭播放器) v2.
2008-8-16 DoubleClickFix 鼠标双击修正工具
2008-8-16 CrystalCPUID 4.15.2.451
2008-8-16 VeryCD 电驴(easyMule) 1.0.4 Bu
2008-8-16 uTorrent 1.8 Build 11813 - Sta
2008-8-16 比特精灵(BitSpirit) v3.3.2.287
2008-8-16 StayInTune音叉 v1.0 破解版
2008-8-16 iChing《周易》汉化补丁 v1.0
2008-8-16 Starmap星空图v1.0汉化破解版
  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号