LCD菜单开发:lcdmenu与submenu类相互调用的编译问题
LCD菜单类与子菜单类互相调用的结构调整问题
我正在开发一款LCD菜单,遇到了lcdmenu(主菜单)与submenu的交互问题。相关代码如下:
class submenu; class lcdmenu { protected: command **commandlist; submenu **submenulist; ... public: void setchildren(command **comlist, submenu **sublist, int comn, int subn); void render(); ... }; void lcdmenu::render(){ lcd_clear(); for (int line = 0; line < MAX_LINES; line ++){ int index = menutop + line; ... if (index < numcommands){ lcd_string(commandlist[index]->get_text()); lcd_string(submenulist[index]->get_text()); }
class submenu : public lcdmenu { public: lcdmenu *parent; submenu(lcdmenu *par, const char* text); const char* get_text(){ return text; } }; submenu::submenu(lcdmenu *par, const char* text_):text(text_), parent(par) { }
我将submenu实例列表传入lcdmenu.submenulist变量,希望lcdmenu::render()能调用lcd_string(submenulist[index]->get_text()),但由于submenu的get_text方法尚未定义,无法实现调用。请问如何调整文件结构,使lcdmenu与submenu两个类能互相完整调用?
解决方案
1. 分离类声明与实现(推荐工程化做法)
将类的声明放在头文件,成员函数实现放在源文件,确保submenu的完整定义在lcdmenu的成员函数实现之前:
头文件(如menu.h)
// 前向声明command类(因lcdmenu中用到了command**) class command; class lcdmenu { protected: command **commandlist; submenu **submenulist; int numcommands; int menutop; // 其他成员变量 public: void setchildren(command **comlist, submenu **sublist, int comn, int subn); void render(); // 其他成员函数声明 }; class submenu : public lcdmenu { private: const char* text; // 补上缺失的text成员变量声明 public: lcdmenu *parent; submenu(lcdmenu *par, const char* text); const char* get_text(){ return text; } };
源文件(如menu.cpp)
#include "menu.h" // 假设lcd_clear、lcd_string、MAX_LINES已提前定义 void lcdmenu::render(){ lcd_clear(); for (int line = 0; line < MAX_LINES; line ++){ int index = menutop + line; // 省略其他逻辑 if (index < numcommands){ lcd_string(commandlist[index]->get_text()); lcd_string(submenulist[index]->get_text()); } } } void lcdmenu::setchildren(command **comlist, submenu **sublist, int comn, int subn){ commandlist = comlist; submenulist = sublist; numcommands = comn; // 其他初始化逻辑 } submenu::submenu(lcdmenu *par, const char* text_): text(text_), parent(par) { // 构造函数逻辑 }
2. 单文件内调整代码顺序
如果不需要分离文件,只需将lcdmenu::render()的实现放在submenu类的完整定义之后,同时补上submenu缺失的text成员变量:
class command; // 前向声明command class lcdmenu { protected: command **commandlist; submenu **submenulist; int numcommands; int menutop; public: void setchildren(command **comlist, submenu **sublist, int comn, int subn); void render(); // 仅声明,不实现 }; class submenu : public lcdmenu { private: const char* text; // 补上缺失的成员变量 public: lcdmenu *parent; submenu(lcdmenu *par, const char* text); const char* get_text(){ return text; } }; // 此时submenu已完整定义,可实现lcdmenu::render void lcdmenu::render(){ lcd_clear(); for (int line = 0; line < MAX_LINES; line ++){ int index = menutop + line; // 省略其他逻辑 if (index < numcommands){ lcd_string(commandlist[index]->get_text()); lcd_string(submenulist[index]->get_text()); } } } // 实现其他成员函数 void lcdmenu::setchildren(command **comlist, submenu **sublist, int comn, int subn){ commandlist = comlist; submenulist = sublist; numcommands = comn; } submenu::submenu(lcdmenu *par, const char* text_): text(text_), parent(par) { }
关键说明
- 原代码中
submenu类缺少text成员变量的声明,必须补上才能正常编译。 - 前向声明仅能让编译器知道类的存在,但无法访问类的成员函数/变量,因此必须确保调用成员函数时,类已经完成完整定义。
内容的提问来源于stack exchange,提问作者Andy Votava
相关产品推荐
相关产品推荐

