类方法中wxString内容消失的原因排查求助
问题:wxString指针内容在构造后丢失
我定义了如下类:
class aeMessage : public aeDialog { const wxString* message; public: aeMessage(const wxString& title, const wxString& message, const char* buttons[], const int button_count, const wxSize& size); void configurePanel(wxPanel* panel); // Overrides method in aeDialog }; aeMessage::aeMessage(const wxString& title, const wxString& message, const char* buttons[], const int button_count, const wxSize& size) : aeDialog(title, buttons, button_count, size) { this->message = &message; std::cout << "1 Message Address = " << this->message << "\n"; std::cout << "2 Message Text = " << *this->message << "\n"; }
构造时输出如下:
1 Message Address = 0x7ff7b9a9b920
2 Message Text = This is the About dialog
我在类中定义了如下方法:
void aeMessage::configurePanel(wxPanel *customPanel) { // Create message box std::cout << "3 Message Address = " << this->message << "\n"; std::cout << "4 Message Text = " << *this->message << "\n"; }
该方法的输出为:
3 Message Address = 0x7ff7b9a9b920
4 Message Text =
类的创建代码如下:
void MyApp::OnAbout(wxCommandEvent &event) { // Show the About dialog box const int numberOfButtons{1}; const char *buttons[numberOfButtons] = {"Ok"}; aeMessage *custom = new aeMessage(wxT("Aetharcana"), "This is the About dialog", buttons, numberOfButtons, wxSize(600, 300)); custom->show(); std::cout << "Returned " << custom->getSelected() << "\n"; custom->Destroy(); }
请问为何字符串内容会消失?没有任何代码修改this->message的内容,恳请帮助。
问题根源与解决方法
核心原因:临时对象生命周期结束导致悬空指针
你在构造函数中保存的message指针指向的是一个临时wxString对象:
- 创建
aeMessage时,传入的字符串字面量"This is the About dialog"会被编译器自动转换为临时wxString对象,这个对象的生命周期仅局限于构造函数的调用过程。 - 构造函数执行完毕后,临时
wxString对象会被销毁,占用的内存被释放,但类中的message指针仍指向这块失效内存——也就是所谓的悬空指针。 - 后续调用
configurePanel时,指针地址没变,但对应内存已不再是有效的wxString数据,因此输出为空。
解决方法
有两种可靠的修复方式:
- 将指针改为成员对象,直接存储wxString
修改类的成员定义,把指针替换为实际的wxString对象,自动拷贝传入的字符串,确保其生命周期与类实例一致:
class aeMessage : public aeDialog { wxString message; // 替换指针为成员对象 public: aeMessage(const wxString& title, const wxString& message, const char* buttons[], const int button_count, const wxSize& size); void configurePanel(wxPanel* panel); }; aeMessage::aeMessage(const wxString& title, const wxString& message, const char* buttons[], const int button_count, const wxSize& size) : aeDialog(title, buttons, button_count, size), message(message) // 初始化列表拷贝字符串 { std::cout << "1 Message Text = " << this->message << "\n"; }
- 确保指针指向的对象生命周期长于类实例
如果必须使用指针,要保证传入的wxString对象在aeMessage实例的整个生命周期内有效。比如在OnAbout中先创建持久化的wxString对象:
void MyApp::OnAbout(wxCommandEvent &event) { const int numberOfButtons{1}; const char *buttons[numberOfButtons] = {"Ok"}; wxString msg = "This is the About dialog"; // 创建持久对象 aeMessage *custom = new aeMessage(wxT("Aetharcana"), msg, buttons, numberOfButtons, wxSize(600, 300)); custom->show(); std::cout << "Returned " << custom->getSelected() << "\n"; custom->Destroy(); }
这种方式需要额外管理对象生命周期,不如第一种方法安全。
内容的提问来源于stack exchange,提问作者Cromwell1963
相关产品推荐
相关产品推荐

