gtkmm:什么是 Glib::RefPtr 个用例?

gtkmm: what is Glib::RefPtr usecases?

我正在用 C++ 和 gtkmm 库编写一个小的 GTK3 应用程序。

在 gtkmm 文档中通常有一些具体实例,例如 Gtk::Application、Gtk::Builder、Gtk::StatusIcon 等,使用 create() 静态方法初始化 return a Glib::RefPtr。同时,子小部件通常只出现在堆栈上。

我不清楚:

Glib::RefPtr 是早于 std::shared_ptr 并执行相同基本功能的引用计数智能指针。它的用例是相似的——它允许多个对象想要共享一个对象的所有权而无需直接相互了解。

在您的具体示例中,一个图标可能会被共享,因为它在 UI 中的多个位置使用,并且您不想维护相同图像数据的多个副本,这可以使用如果有很多图标,需要相当多的内存。

ApplicationBuilder 对象可能由程序中的多个对象持有(例如,不同的 window 或对话框对象),因此引用计数使每个对象保持活动状态因为其中一个对象仍在使用它。这使 Application 对象的这些用户不必了解可能使用共享 Application 对象的程序的所有其他部分。当 window 完成对 Application 的处理后,它会销毁其指向 Application 的智能指针。如果那个 window 是最后一个所有者,这也会破坏 Application 对象,但除此之外,它对其他用户仍然存在——所有这些都没有被破坏的 window 知道 Application 活不活。

  • Is it because memory stack usage or something else? There is no RefPtr's in my code for now. I checked usage of stack with valgrind's massif tool, peak usage was about 100 KB. Seems not too low for me, but comparable size [example with RefPtr's][1] takes a same piece of stack memory.

主要原因是 gtkmm 是一个用 C 编写的 Gtk+ 库的薄 C++ 包装器。Gtk+ 中的大多数对象都分配在堆上(例如,GtkApplication 对象是使用 gtk_application_new function), and are reference counted (manually, using g_object_ref/g_object_unref 函数创建的) .换句话说,这些对象已经共享指针语义,尽管是用普通 C 表示的。因此,在 C++ 中将这些对象表示为智能指针最有意义 - Glib::RefPtr 在这种情况下。

  • May I place all instances just on stack like Application myapp, or should I always use create() while it present?

不,因为 Gtk::Application 构造函数是 protected,所以编译器不允许在堆栈上创建这些对象。

  • What advantages the pointers provide in this case?

我认为恰恰相反。将这些对象保留在堆栈上不会提供任何优势,因为 gtkmm 对象包装的 Gtk 对象本质上是共享指针。