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

时间:2019-02-13 17:24:42

标签: c++ pointers gtkmm

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

在gtkmm文档中,通常使用一些具体实例,例如Gtk :: Application,Gtk :: Builder,Gtk :: StatusIcon等,并使用create()静态方法进行初始化,这些方法会返回Glib :: RefPtr。同时,子小部件通常仅出现在堆栈上。

我不清楚:

  • 是因为内存堆栈使用率高还是其他原因?目前我的代码中没有RefPtr。我使用valgrind的massif工具检查了堆栈的使用情况,峰值使用情况约为100 KB。对我来说似乎不太低,但是可比较的大小example with RefPtr's占用相同的堆栈内存。
  • 我可以将所有实例都像Application myapp一样放在堆栈上吗?还是应该在出现时始终使用create()?
  • 在这种情况下,指针有什么优势?

2 个答案:

答案 0 :(得分:2)

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

在您的特定示例中,可能会共享一个图标,因为它已在UI中的多个位置使用,并且您不想维护同一图像数据的许多副本,如果有的话可能会占用大量内存有很多图标。

ApplicationBuilder对象可能由程序中的多个对象(例如,不同的窗口或对话框对象)保存,因此只要这些对象之一处于活动状态,引用计数就可以使每个对象保持活动状态仍在使用它。这使Application对象的这些用户不必知道程序的所有其他可能使用共享的Application对象的部分。用Application完成一个窗口后,它将破坏指向Application的智能指针。如果该窗口是最后一个所有者,那么这也会破坏Application对象,但是对于其他用户来说,它仍然有效-所有这些都不会使您被破坏的窗口知道Application是否存在。

答案 1 :(得分:0)

  
      
  • 是因为内存堆栈使用率高还是其他原因?目前我的代码中没有RefPtr。我用valgrind检查了堆栈的使用情况   massif工具,峰值使用量约为100 KB。对我来说似乎不太低   但可比尺寸[例如RefPtr的尺寸] [1]占用相同的尺寸   堆栈内存。
  •   

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

  
      
  • 我可以将所有实例都像Application myapp一样放在堆栈上吗?还是应该在出现时始终使用create()?
  •   

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

  
      
  • 在这种情况下,指针有什么优势?
  •   

我认为这是相反的。将这些对象保持在堆栈上不会带来任何好处,因为由gtkmm对象包装的Gtk对象本质上是共享指针。