HelloWindow对象是否被删除?

问题描述

我在GNOME Builder上创建了一个示例GTKMM项目。很棒的事情是为我的示例项目自动生成了示例hello world代码。由于C ++源文件分为三个部分:

  • 头文件
  • 实施文件
  • 主文件

我已经在单个cpp文件中修改了示例代码以进行演示:

#include <iostream>

#include <gtkmm.h>

using std::cout;

using Gtk::Application;
using Gtk::Window;
using Gtk::Box;
using Gtk::Button;
using Gtk::Label;

class HelloWindow : public Window
{
    Box    box;
    Button button;
    Label  label;

public:
    HelloWindow();
    ~HelloWindow();
};

HelloWindow::HelloWindow()
    : Glib::ObjectBase("HelloWindow"),Window(),box(Gtk::ORIENTATION_VERTICAL),button("Clickable button"),label("Hello World!")
{
    set_default_size(320,240);

    bool expand(true),fill(true);
    box.pack_start(label,expand,fill);
    box.pack_end(button,fill);

    add(box);

    show_all();
}

HelloWindow::~HelloWindow()
{
    cout << "Object successfully destructed!\n";
}

static void
on_activate(Glib::RefPtr<Application> app)
{
    Window *window = app->get_active_window();

    if (not window) {
        window = new HelloWindow();
        window->set_application(app);
        app->add_window(*window);
    }

    window->present();
}

int main()
{
    auto app = Application::create("io.test.window-state-event");

    app->signal_activate().connect(sigc::bind(&on_activate,app));

    return app->run();
}

关于上述代码的一个有趣的部分是app连接到on_activate信号,这意味着用户只能运行该程序的一个实例。而且,如果他尝试运行另一个实例,则会显示以前仍在运行的窗口。

但是,在new上使用了on_activate()关键字,这让我有些困惑。当用户关闭HelloWorld窗口时,该对象是否真的删除了?我对C ++ new关键字的了解是,必须记住delete用前一个关键字分配的任何对象。

此外,析构函数消息“对象已成功破坏!”关闭窗口时不会打印。

解决方法

有可能是故意泄漏,但它是“受控的”。作者知道该方法将仅被调用一次。作者还知道内存需要在应用程序的整个生命周期内保持活动状态。当应用程序关闭时,该内存将以一种或另一种方式释放(尽管不会调用析构函数,但是在这种情况下,不需要执行任何操作)

这种方案中完全可以。

如果要确保删除Window对象,可以保留unique_ptr中的Window,它会自行处置(由于@underscore_d注释):

#include <memory>

static std::unique_ptr<Window> window;

static void
on_activate(Glib::RefPtr<Application> app)
{
    if (!window) {
        window = std::make_unique<HelloWindow>();
        window->set_application(app);
        app->add_window(*window);
    }

    window->present();
}

int main()
{
    auto app = Application::create("io.test.window-state-event");
    app->signal_activate().connect(sigc::bind(&on_activate,app));
    return app->run();
}

最终,我确定作者希望保持这个“ Hello,World”示例简单明了,并且不想添加一些实际上不是 的代码>保持简洁简洁。

,

请参阅GTKMM文档中有关managed widgets的部分。您应该使用Gtk::make_managed的一些变体:

if (!window) {
    window = Gtk::make_managed<HelloWindow>();
    window->set_application(app);
    app->add_window(*window);
}

这样,窗口的生存期将由应用程序管理。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...