You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++虚函数两种定义方式的区别及TouchGFX编译错误解析

TouchGFX开发中虚函数声明与定义的区别及编译错误解决

问题场景

  • 基于TouchGFX开发多界面显示项目,项目包含全局Model和ModelListener类,每个界面对应Presenter和View类
  • 已完成PrincipalScreen相关类的实现,但SecondScreen的Presenter未正确处理ModelListener中的虚函数
  • Model类的tick函数会通过ModelListener调用setTimeDate方法,触发时间更新通知

编译错误信息

./Application/User/gui/SecondScreenPresenter.o:(.rodata._ZTV21SecondScreenPresenter+0x28):undefined reference to `ModelListener::setTime(displayTime_t)'

解决方法

将ModelListener中的虚函数从仅声明改为带空实现的定义:

  • 错误写法(仅声明):
    virtual void setTime(displayTime_t time); // #1 报错
    
  • 正确写法(声明+空定义):
    virtual void setTime(displayTime_t time){} // #2 正确
    

两种写法的核心区别(结合C++与TouchGFX架构)

1. 仅虚函数声明(无定义)

这是普通虚函数的声明,但未提供实现代码:

  • 编译器会为包含该函数的类生成虚函数表(vtable),但表中该函数的地址是缺失的
  • 当子类(比如SecondScreenPresenter)继承该类且未重写这个虚函数时,链接器找不到函数的实现,就会抛出"undefined reference"错误
  • 在TouchGFX场景中,Model通过ModelListener指针调用setTime时,会尝试找到该函数的实现,找不到就触发报错

2. 带空大括号的虚函数定义

这是同时完成了虚函数的声明与空实现:

  • 编译器会把这个空实现的地址填入虚函数表
  • 如果子类没有重写该函数,调用时会执行这个空实现,不会触发链接错误
  • 对于暂时不需要处理时间更新的SecondScreen来说,这种写法既满足了链接器的要求,又不需要额外的逻辑代码

TouchGFX开发中的注意事项

  • ModelListener是TouchGFX中用于Model向各个Presenter推送数据更新的接口类,通常定义一系列虚函数
  • 如果你希望某个更新逻辑必须被子类实现,可以把该函数定义为纯虚函数(virtual void setTime(displayTime_t time) = 0;),此时基类不需要实现,子类必须重写才能实例化
  • 对于不需要处理的更新逻辑,用空实现的虚函数即可避免编译错误

内容的提问来源于stack exchange,提问作者Rodo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:03:37