[gtkmm-documentation/wip/dboles/make_managed-etc-4: 4/5] Document the new make_managed() & prefer to use it



commit 71b74d38dc8441fca8cfc68cb7b7d48caa549b27
Author: Daniel Boles <dboles src gmail com>
Date:   Wed Nov 7 17:58:34 2018 +0000

    Document the new make_managed() & prefer to use it
    
    This performs creation and manage()ment in a single step and therefore
    avoids the user having to write the discouraged new operator, looks more
    like Standard C++ things like make_shared(), etc. So, move our examples
    to it, and elaborate on why it is preferable to manage() or new/delete.
    
    https://gitlab.gnome.org/GNOME/gtkmm/issues/33

 docs/tutorial/C/index-in.docbook | 84 +++++++++++++++++++++++++++-------------
 1 file changed, 57 insertions(+), 27 deletions(-)
---
diff --git a/docs/tutorial/C/index-in.docbook b/docs/tutorial/C/index-in.docbook
index ce2c1aa..45429dc 100644
--- a/docs/tutorial/C/index-in.docbook
+++ b/docs/tutorial/C/index-in.docbook
@@ -423,7 +423,15 @@ Most of the chapters in this book deal with specific widgets. See the <link link
 <para>Although you can specify the layout and appearance of windows and widgets with C++ code, you will 
probably find it more convenient to design your user interfaces with <literal>Glade</literal> and load them 
at runtime with <literal>Gtk::Builder</literal>. See the <link linkend="chapter-builder">Glade and 
Gtk::Builder</link> chapter.
 </para>
 
-<para>Although &gtkmm; widget instances have lifetimes and scopes just like those of other C++ classes, 
&gtkmm; has an optional time-saving feature that you will see in some of the examples. 
<function>Gtk::manage()</function> allows you to say that a child widget is owned by the container into which 
you place it. This allows you to <function>new</function> the widget, add it to the container and forget 
about deleting it. You can learn more about &gtkmm; memory management techniques in the <link 
linkend="chapter-memory">Memory Management chapter</link>.
+<para>Although &gtkmm; widget instances have lifetimes and scopes just like
+those of other C++ classes, &gtkmm; has an optional time-saving feature that you
+will see in some of the examples. The <function>Gtk::make_managed()</function>
+allows you to create a new widget and state that it will become owned by the
+container into which you place it. This allows you to create the widget, add it
+to the container and not be concerned about deleting it, since that will occur
+when the parent container (which may itself be managed) is deleted. You can
+learn more about &gtkmm; memory management techniques in the
+<link linkend="chapter-memory">Memory Management chapter</link>.
 </para>
 
 </sect1>
@@ -503,7 +511,7 @@ The C++ wrapper shall be explicitly deleted if
 <itemizedlist>
 <listitem><para>it's a widget or other class that inherits from <classname>Gtk::Object</classname>, 
and</para></listitem>
 <listitem><para>the C instance has a floating reference when the wrapper is created, and</para></listitem>
-<listitem><para><function>Gtk::manage()</function> has not been called on it, or</para></listitem>
+<listitem><para><function>Gtk::manage()</function> has not been called on it (which includes if it was 
created with <function>Gtk::make_managed()</function>), or</para></listitem>
 <listitem><para><function>Gtk::manage()</function> was called on it, but it was never added to, or was later 
removed from, its parent.</para></listitem>
 </itemizedlist>
 <function>Glib::wrap()</function> binds the C and C++ instances to each other.
@@ -980,9 +988,9 @@ public:
 RadioButtons::RadioButtons()
 {
   Gtk::RadioButton::Group group;
-  Gtk::RadioButton* m_rb1 = Gtk::manage(new Gtk::RadioButton(group, "button1"));
-  Gtk::RadioButton* m_rb2 = Gtk::manage(new Gtk::RadioButton(group, "button2"));
-  Gtk::RadioButton* m_rb3 = Gtk::manage(new Gtk::RadioButton(group, "button3"));
+  Gtk::RadioButton* m_rb1 = Gtk::make_managed<Gtk::RadioButton>(group, "button1");
+  Gtk::RadioButton* m_rb2 = Gtk::make_managed<Gtk::RadioButton>(group, "button2");
+  Gtk::RadioButton* m_rb3 = Gtk::make_managed<Gtk::RadioButton>(group, "button3");
 }</programlisting>
 
 <para>
@@ -2516,7 +2524,7 @@ appropriate <classname>Gtk::TreeView::Column</classname> widget.
 Here is some example code, which has a pixbuf icon and a text name in the same column:
 </para>
 <programlisting>Gtk::TreeView::Column* pColumn =
-  Gtk::manage(new Gtk::TreeView::Column("Icon Name"));
+  Gtk::make_managed<Gtk::TreeView::Column>("Icon Name");
 
 // m_columns.icon and m_columns.iconname are columns in the model.
 // pColumn is the column in the TreeView:
@@ -2550,7 +2558,7 @@ if(pColumn)
 actions. For instance:
 </para>
 <programlisting>Gtk::CellRendererToggle* pRenderer =
-    Gtk::manage( new Gtk::CellRendererToggle() );
+    Gtk::make_managed<Gtk::CellRendererToggle>();
 pRenderer-&gt;signal_toggled().connect(
     sigc::bind( sigc::mem_fun(*this,
         &amp;Example_TreeView_TreeStore::on_cell_toggled), m_columns.dave)
@@ -3528,7 +3536,7 @@ to a container. For instance:
 <programlisting>
 <![CDATA[Glib::RefPtr<Glib::Object> object = m_refBuilder->get_object("menubar");
 Glib::RefPtr<Gio::Menu> gmenu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
-Gtk::MenuBar* pMenuBar = Gtk::manage(new Gtk::MenuBar(gmenu));
+Gtk::MenuBar* pMenuBar = Gtk::make_managed<Gtk::MenuBar>(gmenu);
 m_Box.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
 
 Gtk::Toolbar* toolbar = nullptr;
@@ -5262,7 +5270,7 @@ Gtk::Widget* CustomPrintOperation::on_create_custom_widget()
   Gtk::Box* hbox = new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 8);
   hbox-&gt;set_margin(6);
 
-  Gtk::Label* label = Gtk::manage(new Gtk::Label("Enter some text: "));
+  Gtk::Label* label = Gtk::make_managed<Gtk::Label>("Enter some text: ");
   hbox-&gt;pack_start(*label, false, false);
 
   hbox-&gt;pack_start(m_Entry, false, false);
@@ -5993,11 +6001,13 @@ increased data hiding and reduced dependencies.
 <title>Dynamic allocation with new and delete</title>
 
 <para>
-Although, in most cases, the programmer will prefer to allow containers to
-automatically destroy their children using <function>Gtk::manage()</function> (see
-below), the programmer is not required to use <function>Gtk::manage()</function>.
-The traditional <literal>new</literal> and <literal>delete</literal> operators
-may also be used.
+Usually, the programmer will prefer to allow containers to automatically destroy
+their children by creating them using <function>Gtk::make_managed()</function>
+(see below). This is not strictly required, as the <literal>new</literal> and
+<literal>delete</literal> operators may also be used, but modern C++ style
+discourages those in favour of safer models of memory management, so it is
+better to create widgets using <function>Gtk::make_managed()</function> and
+let their parent destroy them, than to manually perform dynamic allocation.
 <programlisting>
 Gtk::Button* pButton = new Gtk::Button("Test");
 
@@ -6018,29 +6028,47 @@ Here, the programmer deletes <varname>pButton</varname> to prevent a memory leak
 Alternatively, you can let a widget's container control when the widget is
 destroyed. In most cases, you want a widget to last only as long as the
 container it is in. To delegate the management of a widget's lifetime to its
-container, first create it with <function>Gtk::manage()</function> and
+container, create it with <function>Gtk::make_managed()</function> and then
 pack it into its container with <methodname>Gtk::Container::add()</methodname>,
 <methodname>Gtk::Box::pack_start()</methodname>, or a similar method. Now the
 widget will be destroyed whenever its container is destroyed.
 </para>
 
 <sect3 id="memory-managed-dynamic">
-<title>Dynamic allocation with manage() and add()</title>
+<title>Dynamic allocation with make_managed() and add()</title>
 
 <para>
-&gtkmm; provides the <function>manage()</function> function and
-<methodname>add()</methodname> and similar methods to create and destroy widgets. Every widget
-except a top-level window must be added or packed into a container in order to
-be displayed. The <function>manage()</function> function marks a widget
-so that when the widget is added to a container, the container becomes
+&gtkmm; provides ways including the <function>make_managed()</function> function
+and <methodname>Gtk::Container::add()</methodname> method to simplify creation
+and destruction of widgets whose lifetime can be managed by a parent.
+</para>
+
+<para>
+Every widget except a top-level window must be added to a parent container in
+order to be displayed. The <function>manage()</function> function marks a widget
+so that when that widget is added to a parent container, said container becomes
 responsible for deleting the widget, meaning the user no longer needs to do so.
+The original way to create widgets whose lifetime is managed by their parent in
+this way was to call <function>manage()</function>, passing in the result of a
+<literal>new</literal> expression that created a dynamically allocated widget.
+</para>
+
+<para>
+However, usually, when you create such a widget, you will already know that its
+parent container should be responsible for destroying it, In addition, modern
+C++ style discourages use of the <literal>new</literal> operator, which was
+required when passing a newly created widget to <function>manage()</function>.
+Therefore, &gtkmm; has added <function>make_managed()</function>, which combines
+creation and marking with <function>manage()</function> into a single step. This
+avoids you having to write <literal>new</literal>, which is discouraged in
+modern C++ style, and more clearly expresses intent to create a managed widget.
 </para>
 
 <para>
 <programlisting>
 MyContainer::MyContainer()
 {
-  Gtk::Button* pButton = Gtk::manage(new Gtk::Button("Test"));
+  Gtk::Button* pButton = Gtk::make_managed<Gtk::Button>("Test");
   add(*pButton); //add *pButton to MyContainer
 }
 </programlisting>
@@ -9452,11 +9480,13 @@ _CLASS_GTKOBJECT(Button, GtkButton, GTK_BUTTON, Gtk::Bin, GtkBin)
     <classname>Gtk::Object</classname>. For instance, you will use it when wrapping
     a GTK+ Widget, because <classname>Gtk::Widget</classname> derives from
     <classname>Gtk::Object</classname>.</para>
-<para>You might also derive non-widget classes from <classname>Gtk::Object</classname>
-    so they can be used without <classname>Glib::RefPtr</classname>. For instance,
-    they could then be instantiated with <function>Gtk::manage()</function> or on the stack
-    as a member variable. This is convenient, but you should use this only when you are sure
-    that true reference-counting is not needed. We consider it useful for widgets.</para>
+<para>You might also derive non-widget classes from
+    <classname>Gtk::Object</classname> so they can be used without
+    <classname>Glib::RefPtr</classname>. For instance, they could then be
+    instantiated with <function>Gtk::make_managed()</function> or on the stack
+    as a member variable. This is convenient, but you should use this only when
+    you are sure that true reference-counting is not needed. We consider it
+    useful for widgets.</para>
 </sect3>
 
 <sect3 id="gmmproc-class-boxedtype">


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]