SFML自定义类封装sf::Text存入数组后显示异常如何修复
问题根因
你的判断完全正确。SFML中sf::Text不持有字体资源,仅保存传入sf::Font对象的指针,你当前代码的问题出在默认生成的浅拷贝逻辑:
- 循环内创建的临时
someText对象,_text成员绑定的是临时对象自身_font的地址 - 单次迭代结束临时对象析构,内部
_font被销毁,数组中拷贝得到的对象的_text持有悬空字体指针 - 渲染时无法读取有效字体轮廓数据,文本就会显示为单个像素点
循环外额外创建对象后能正常显示属于内存未被覆写的巧合,不是可稳定依赖的逻辑。
最简修复方案
无冗余代码,两种方案按需选择即可:
方案1:禁止拷贝,直接初始化数组(推荐,零额外开销)
- 在类定义中删除默认生成的拷贝构造、拷贝赋值运算符,从根源避免浅拷贝问题
- 不再先创建默认构造的空数组再循环赋值,直接在数组定义时初始化元素,全程不存在临时对象拷贝
核心代码:
// someText.h 类内 public 区域添加 someText(const someText&) = delete; someText& operator=(const someText&) = delete; // main.cpp 中数组初始化改为直接构造 someText textArr[3] = { someText("第一个按钮"), someText("第二个按钮"), someText("第三个按钮") };
方案2:自定义拷贝逻辑适配赋值场景
如果业务逻辑确实需要运行时赋值对象,手动实现拷贝构造、拷贝赋值运算符,拷贝完成后重新为_text绑定当前对象的_font地址:
// someText.cpp 中补充实现 someText::someText(const someText& other) : _font(other._font), _text(other._text) { _text.setFont(_font); // 重新绑定当前对象的字体 } someText& someText::operator=(const someText& other) { if (this == &other) return *this; _font = other._font; _text = other._text; _text.setFont(_font); // 重新绑定当前对象的字体 return *this; }
优化提示:
sf::Font是重型资源,实际项目中建议多个文本/按钮对象共享同一份加载好的字体实例,不要每个对象单独加载字体文件,可以显著降低内存占用、提升加载速度。
内容的提问来源于stack exchange,提问作者Hygiea
相关产品推荐
相关产品推荐

