gtkmm:什么是 Glib::RefPtr 个用例?
gtkmm: what is Glib::RefPtr usecases?
我正在用 C++ 和 gtkmm 库编写一个小的 GTK3 应用程序。
在 gtkmm 文档中通常有一些具体实例,例如 Gtk::Application、Gtk::Builder、Gtk::StatusIcon 等,使用 create() 静态方法初始化 return a Glib::RefPtr。同时,子小部件通常只出现在堆栈上。
我不清楚:
- 是内存栈占用还是其他原因?目前我的代码中没有 RefPtr。我用 valgrind 的 massif 工具检查了堆栈的使用情况,峰值使用量约为 100 KB。对我来说似乎并不太低,但可比较的大小 example with RefPtr's 占用相同的堆栈内存。
- 我可以像
Application myapp
一样将所有实例都放在堆栈上,还是应该在它存在时始终使用 create()?
- 在这种情况下指针有什么优势?
Glib::RefPtr
是早于 std::shared_ptr
并执行相同基本功能的引用计数智能指针。它的用例是相似的——它允许多个对象想要共享一个对象的所有权而无需直接相互了解。
在您的具体示例中,一个图标可能会被共享,因为它在 UI 中的多个位置使用,并且您不想维护相同图像数据的多个副本,这可以使用如果有很多图标,需要相当多的内存。
Application
和 Builder
对象可能由程序中的多个对象持有(例如,不同的 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 对象本质上是共享指针。
我正在用 C++ 和 gtkmm 库编写一个小的 GTK3 应用程序。
在 gtkmm 文档中通常有一些具体实例,例如 Gtk::Application、Gtk::Builder、Gtk::StatusIcon 等,使用 create() 静态方法初始化 return a Glib::RefPtr。同时,子小部件通常只出现在堆栈上。
我不清楚:
- 是内存栈占用还是其他原因?目前我的代码中没有 RefPtr。我用 valgrind 的 massif 工具检查了堆栈的使用情况,峰值使用量约为 100 KB。对我来说似乎并不太低,但可比较的大小 example with RefPtr's 占用相同的堆栈内存。
- 我可以像
Application myapp
一样将所有实例都放在堆栈上,还是应该在它存在时始终使用 create()? - 在这种情况下指针有什么优势?
Glib::RefPtr
是早于 std::shared_ptr
并执行相同基本功能的引用计数智能指针。它的用例是相似的——它允许多个对象想要共享一个对象的所有权而无需直接相互了解。
在您的具体示例中,一个图标可能会被共享,因为它在 UI 中的多个位置使用,并且您不想维护相同图像数据的多个副本,这可以使用如果有很多图标,需要相当多的内存。
Application
和 Builder
对象可能由程序中的多个对象持有(例如,不同的 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 对象本质上是共享指针。