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

类方法中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数据,因此输出为空。

解决方法

有两种可靠的修复方式:

  1. 将指针改为成员对象,直接存储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";
}
  1. 确保指针指向的对象生命周期长于类实例
    如果必须使用指针,要保证传入的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:54:59