4628|0

367

帖子

0

TA的资源

裸片初长成(高级)

楼主
 

求助后的总结报告 [复制链接]

正确而简单地说应该使用静态类成员的指针而非指向类成员的指针 正如John_Lee所述的两个方法的分析,后者确实把简单问题复杂话了. 因为静态类成员是属于该类的全局对象和函数,它的指针是普通指针.引用该指针不需要类对象. 而类成员的指针必须总是通过特定的对象或指向该类类型的对象的指针来访问. 再者GCCAVR取FLASH数据必须通过pgm_read_word函数形成汇编代码LPM指令才能取出跳转地址. 而且将其转换为类成员的指针我和John_Lee一样都不能找到更好地方法,只能通过嵌入汇编语句完成. 这样也失去了C++的特色. 所以,静态类成员的指针应该是不错的方法.所以Key00()等函数必须声明为静态函数,这样才能在 KeyCommandTab[]函数指针数组中以函数名即函数的装载地址的身份出现,这样就实现了不同函数的散转. 至于函数指针数组是定义为静态类成员或在类成员函数中出现都无关紧要,但有一点是可以肯定的,那就是也必须 定义为静态数组,而且前者必须在类体外初始化,后者可以直接初始化. 特别注意后者虽可不定义为静态数组,但它 将会将数组装载在RAM中.例: class KeyObj { public: KeyObj(void); void Exec(void);//每2.5mS中断调用一次, KeyCount会自动+1 private: void KeyInit(void); unsigned char GetKeyVal(void); void KeyCommandExec(unsigned char);//测试时需声明为public //................ static void Key00(void);//必须声明为static!!! //................ static void Key24(void);//必须声明为static!!! };//键盘模块 typedef void (* PFV)(void);//普通函数指针 void KeyObj::KeyCommandExec(unsigned char mode) { static PFV KeyCommandTab[3][5] PROGMEM = {//键盘放事件处理表//必须声明为static!!!否则忽略PROGMEM {Key00, Key01, Key02, Key03, Key04}, //键释放事件处理 {Key10, Key11, Key12, Key13, Key14}, //压键事件处理 {Key20, Key21, Key22, Key23, Key24} //长压键事件处理 }; PFV func;//定义普通函数指针 KeyCount &= 0x07;//取键盘序号//使用1602字节(.text),运行正确 if (KeyCount <= 4) {//只有5个键,KeyCount>=5为3个短接线. func = reinterpret_cast<PFV>(pgm_read_word(&KeyCommandTab[mode][KeyCount]));//取flash键盘放事件处理表 func();//运行KeyX0()~KeyX4() } } 最后感觉KeyCommandTab[]函数数组指针还是定义在类成员函数KeyCommandExec()为好,因为其他成员并不需要访问KeyCommandTab[]. 当然这样做会在不了解KeyCommandTab[]要取Key00()等函数指针时会把对Key00()等定义为静态函数产生疑问. 如果其他成员并需要访问KeyCommandTab[],则改为: PFV func;//定义普通函数指针 class KeyObj { public: KeyObj(void); void Exec(void);//每2.5mS中断调用一次, KeyCount会自动+1 private: void KeyInit(void); unsigned char GetKeyVal(void); void KeyCommandExec(unsigned char);//测试时需声明为public //................ static const PFV KeyCommandTab[3][5];//必须声明为static!!! static void Key00(void);//必须声明为static!!! //................ static void Key24(void);//必须声明为static!!! };//键盘模块 //初始化键盘放事件处理表,因为KeyCommandTab数组为静态成员,故必须在类体外进行初始化 const PFV KeyObj::KeyCommandTab[3][5] PROGMEM = {//键盘放事件处理表 {Key00, Key01, Key02, Key03, Key04}, //键释放事件处理 {Key10, Key11, Key12, Key13, Key14}, //压键事件处理 {Key20, Key21, Key22, Key23, Key24} //长压键事件处理 }; void KeyObj::KeyCommandExec(unsigned char mode) { PFV func;//定义普通函数指针 KeyCount &= 0x07;//取键盘序号//使用1602字节(.text),运行正确 if (KeyCount <= 4) {//只有5个键,KeyCount>=5为3个短接线. //由于KeyCommandExec()函数也是KeyObj的类成员函数,故可直接访问KeyCommandTab[]数组 func = reinterpret_cast<PFV>(pgm_read_word(&KeyCommandTab[mode][KeyCount]));//取flash键盘放事件处理表 func();//运行KeyX0()~KeyX4() } } 现在和求助帖对比发现也就"static"一词之差,但结果却相差万里. 此帖到此讨论结束,也作为我对求助的总结"报告". 我认为求助而不总结的都是些"白帖",总结后就会知道自己永远还是一只不会飞的大菜鸟. 我很菜但我肯吃苦,我虽笨但我更努力. 我灌水但我不害人,我无翅但我梦飞翔. 再次感谢John_Lee和testcode两位网友!
此帖出自单片机论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表