构造函数执行后类成员Buffer地址变更问题求助(C++)
问题根源与解决方案
核心问题在于Editor和InputManager类中的textContent成员是值类型而非引用类型,导致构造时发生了对象拷贝,后续两个类操作的是原TextContent对象的独立副本,而非同一个原对象。
具体分析
你在构造函数中打印的是传入的content(原对象)的buffer地址,此时确实和原对象一致。但如果你的Editor/InputManager类定义是类似这样:
class Editor { sf::RenderWindow window; TextContent textContent; // 这里是值类型,会拷贝对象 public: Editor(sf::RenderWindow& window, TextContent& content) : window(window), textContent(content) {} };
初始化列表中的textContent(content)会调用TextContent的拷贝构造函数(如果没自定义,编译器会生成默认拷贝构造),创建一个新的TextContent对象作为Editor的成员。后续访问editor.textContent.buffer时,访问的是这个拷贝对象的buffer,地址自然和原对象不同——InputManager同理,它也持有另一个独立拷贝。
修复方法
把Editor和InputManager中的textContent成员改为引用类型,这样两个类就会直接引用原TextContent对象,而非持有拷贝:
- 修改Editor类定义:
class Editor { sf::RenderWindow& window; // 注意window也应该用引用,避免拷贝sf::RenderWindow TextContent& textContent; // 改为引用类型 public: // 引用必须在初始化列表中初始化 Editor(sf::RenderWindow& window, TextContent& content) : window(window), textContent(content) { std::cout << "Buffer in Editor constructor" << std::endl; std::cout << &textContent.buffer << std::endl; // 此时打印的就是原对象的buffer地址 } };
- 同理修改InputManager类:
class InputManager { TextContent& textContent; // 改为引用类型 public: InputManager(TextContent& content) : textContent(content) { std::cout << "Buffer in InputManager constructor" << std::endl; std::cout << &textContent.buffer << std::endl; } };
注意事项
- 引用类型的成员必须在类的构造函数初始化列表中完成初始化,不能在构造函数体内赋值。
- 要确保原TextContent对象的生命周期长于Editor和InputManager对象(你的main函数中
content先创建,editor和in_manager后创建,满足这个条件,不会出现悬空引用问题)。
修改后,两个类访问的都是同一个原TextContent对象的buffer,修改InputManager中的buffer时,Editor中的buffer会同步更新,地址也会始终保持一致。
内容的提问来源于stack exchange,提问作者MikeDarni
相关产品推荐
相关产品推荐

