HelloWindow 对象是否被删除?
Is HelloWindow object deleted?
我在 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, expand, 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
信号,这意味着用户只能 运行 该程序的一个实例。如果他尝试 运行 另一个实例,则会显示之前的 运行ning window。
但是,在 on_activate()
上使用了 new
关键字,这让我有点困惑。当用户关闭 HelloWorld window 时,对象真的被删除了吗?我对 C++ new
关键字的了解是,必须记住 delete
使用前一个关键字分配的任何对象。
此外,析构函数消息“对象已成功销毁!” window 关闭时不打印。
可能存在故意泄漏,但它是“受控的”。作者知道这个方法只会被调用一次。作者还知道内存需要在应用程序的整个生命周期内处于活动状态。当应用程序关闭时,该内存将以一种或另一种方式释放(尽管永远不会调用析构函数,但在这种情况下,不需要做任何必要的事情)
在这种场景下完全没问题。
如果你想确保 Window
对象被删除,你可以保留 Window
的 unique_ptr
它会自行处理(感谢 @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);
}
这样,window 的生命周期将由应用程序管理。
我在 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, expand, 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
信号,这意味着用户只能 运行 该程序的一个实例。如果他尝试 运行 另一个实例,则会显示之前的 运行ning window。
但是,在 on_activate()
上使用了 new
关键字,这让我有点困惑。当用户关闭 HelloWorld window 时,对象真的被删除了吗?我对 C++ new
关键字的了解是,必须记住 delete
使用前一个关键字分配的任何对象。
此外,析构函数消息“对象已成功销毁!” window 关闭时不打印。
可能存在故意泄漏,但它是“受控的”。作者知道这个方法只会被调用一次。作者还知道内存需要在应用程序的整个生命周期内处于活动状态。当应用程序关闭时,该内存将以一种或另一种方式释放(尽管永远不会调用析构函数,但在这种情况下,不需要做任何必要的事情)
在这种场景下完全没问题。
如果你想确保 Window
对象被删除,你可以保留 Window
的 unique_ptr
它会自行处理(感谢 @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);
}
这样,window 的生命周期将由应用程序管理。