title: Creation of objects by using a primitive operation
body: <p>My question contains a longer piece of Ada code. Basically I tried to model a message with a title in a object oriented way. The two primitive operations <code>Create_Message</code> and <code>Create_Message_Access</code> can be used to create concrete message objects. I'm not really sure if the primitive operation should return the type <code>Message_Type</code> or <code>Message_Type_Access</code>. Which type is recommended (efficiency?) or are both solutions are not optimal?</p>
  
  <p>I think in the first way the object is created on the stack and then copied after the <code>return</code> statement is executed because the variable <code>Object</code> goes out of scope. Right or wrong?</p>
  
  <pre class="lang-ada prettyprint-override"><code>function Create_Message (Title : String) return Message_Type is
     Object : Message_Type;
  begin
     Object.Title := To_Unbounded_String (Title);
  
     return Object;
  end Create_Message;
  </code></pre>
  
  <p>I think in the second way the object is created on the heap and then the <strong>pointer</strong> is copied after the <code>return</code> statement is executed because the variable <code>Object</code> goes out of scope. Right or wrong?</p>
  
  <pre class="lang-ada prettyprint-override"><code>function Create_Message_Access (Title : String) return Message_Type_Access is
     Object : Message_Type_Access := new Message_Type;
  begin
     Object.Title := To_Unbounded_String (Title);
  
     return Object;
  end Create_Message_Access;
  </code></pre>
  
  <p>Later I created an example object with a title, used the primitive operation <code>Updated_Title</code> to change the title and change it back at the end.</p>
  
  <pre class="lang-ada prettyprint-override"><code>First_Message := Message.Create_Message ("First");
  
  Ada.Text_IO.Put_Line (First_Message.Get_Title);
  
  First_Message.Update_Title ("First changed");
  
  Ada.Text_IO.Put_Line (First_Message.Get_Title);
  
  First_Message.Update_Title ("First");
  
  Ada.Text_IO.Put_Line (First_Message.Get_Title); 
  </code></pre>
  
  <p>The output is (as expected):</p>
  
  <pre><code>First
  First changed
  First
  </code></pre>
  
  <p>Then I saved the message in a vector container and tried to change the title while iterating over the elements stored in the vector. I found out that the title keeps the old value so I assume calling the operation <code>Message_Vector.Element (Message_Cursor)</code> returns only a copy of the message stored in the vector. Right or wrong?</p>
  
  <pre class="lang-ada prettyprint-override"><code>Messages.Append (First_Message);
  
  Message_Cursor := Message_Vector.First (Messages);
  
  while Message_Vector.Has_Element (Message_Cursor) loop
     declare
        Temporary_Message : Message.Message_Type;
     begin
        Temporary_Message := Message_Vector.Element (Message_Cursor);
        Temporary_Message.Update_Title ("First changed");
     end;
  
     Message_Vector.Next (Message_Cursor);
  end loop;
  
  Message_Cursor := Message_Vector.First (Messages);
  
  while Message_Vector.Has_Element (Message_Cursor) loop
     --
     -- Prints "First" and not "First changed"
     --
     Ada.Text_IO.Put_Line (Message_Vector.Element (Message_Cursor).Get_Title);
  
     Message_Vector.Next (Message_Cursor);
  end loop;
  </code></pre>
  
  <p>Last question: What is the difference between <code>Second_Message.all.Get_Title</code> and <code>Second_Message.Get_Title</code>?</p>
  
  <pre class="lang-ada prettyprint-override"><code>Second_Message := Message.Create_Message_Access ("Second");
  
  Ada.Text_IO.Put_Line (Second_Message.all.Get_Title);
  Ada.Text_IO.Put_Line (Second_Message.Get_Title);
  </code></pre>
  
  <p>Full source code:</p>
  
  <pre class="lang-ada prettyprint-override"><code>with Ada.Containers.Vectors;
  with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
  
  with Ada.Text_IO;
  
  procedure Main is
  
     package Message is
  
        type Message_Type is tagged private;
  
        type Message_Type_Access is access Message_Type;
  
        function Create_Message (Title : String) return Message_Type;
  
        function Create_Message_Access (Title : String) return Message_Type_Access;
  
        function Get_Title (Self : Message_Type) return String;
  
        procedure Update_Title (Self : in out Message_Type; Title : String);
  
        function "=" (Left, Right : Message_Type) return Boolean;
  
     private
  
        type Message_Type is tagged record
           Title : Unbounded_String;
        end record;
  
     end Message;
  
     package body Message is
  
        function Create_Message (Title : String) return Message_Type is
           Object : Message_Type;
        begin
           Object.Title := To_Unbounded_String (Title);
  
           return Object;
        end Create_Message;
  
        function Create_Message_Access (Title : String) return Message_Type_Access is
           Object : Message_Type_Access := new Message_Type;
        begin
           Object.Title := To_Unbounded_String (Title);
  
           return Object;
        end Create_Message_Access;
  
        function Get_Title (Self : Message_Type) return String is
        begin
           return To_String (Self.Title);
        end Get_Title;
  
        procedure Update_Title (Self : in out Message_Type; Title : String) is
        begin
           Self.Title := To_Unbounded_String (Title);
        end Update_Title;
  
        function "=" (Left, Right : Message_Type) return Boolean is
        begin
           return Left.Title = Right.Title;
        end "=";
  
     end Message;
  
     package Message_Vector is new Ada.Containers.Vectors (Index_Type =&gt; Natural,
        Element_Type =&gt; Message.Message_Type, "=" =&gt; Message."=");
  
     package Message_Access_Vector is new Ada.Containers.Vectors (Index_Type =&gt; Natural,
        Element_Type =&gt; Message.Message_Type_Access, "=" =&gt; Message."=");
  
     Messages       : Message_Vector.Vector;
     Message_Cursor : Message_Vector.Cursor;
  
     Messages_Access       : Message_Access_Vector.Vector;
     Message_Access_Cursor : Message_Access_Vector.Cursor;
  
     First_Message  : Message.Message_Type;
     Second_Message : Message.Message_Type_Access;
  
  begin
     First_Message := Message.Create_Message ("First");
  
     Ada.Text_IO.Put_Line (First_Message.Get_Title);
  
     First_Message.Update_Title ("First changed");
  
     Ada.Text_IO.Put_Line (First_Message.Get_Title);
  
     First_Message.Update_Title ("First");
  
     Ada.Text_IO.Put_Line (First_Message.Get_Title);
  
     --
  
     Ada.Text_IO.New_Line;
  
     Messages.Append (First_Message);
  
     Message_Cursor := Message_Vector.First (Messages);
  
     while Message_Vector.Has_Element (Message_Cursor) loop
        declare
           Temporary_Message : Message.Message_Type;
        begin
           Temporary_Message := Message_Vector.Element (Message_Cursor);
           Temporary_Message.Update_Title ("First changed");
        end;
  
        Message_Vector.Next (Message_Cursor);
     end loop;
  
     Message_Cursor := Message_Vector.First (Messages);
  
     while Message_Vector.Has_Element (Message_Cursor) loop
        --
        -- Prints "First" and not "First changed"
        --
        Ada.Text_IO.Put_Line (Message_Vector.Element (Message_Cursor).Get_Title);
  
        Message_Vector.Next (Message_Cursor);
     end loop;
  
     --
  
     Ada.Text_IO.New_Line;
  
     Second_Message := Message.Create_Message_Access ("Second");
  
     Ada.Text_IO.Put_Line (Second_Message.all.Get_Title);
     Ada.Text_IO.Put_Line (Second_Message.Get_Title);
  
     --
  
     Ada.Text_IO.New_Line;
  
     Messages_Access.Append (Second_Message);
  
     Message_Access_Cursor := Message_Access_Vector.First (Messages_Access);
  
     while Message_Access_Vector.Has_Element (Message_Access_Cursor) loop
        declare
           Temporary_Message : Message.Message_Type_Access;
        begin
           Temporary_Message := Message_Access_Vector.Element (Message_Access_Cursor);
           Temporary_Message.Update_Title ("Second changed");
        end;
  
        Message_Access_Vector.Next (Message_Access_Cursor);
     end loop;
  
     Message_Access_Cursor := Message_Access_Vector.First (Messages_Access);
  
     while Message_Access_Vector.Has_Element (Message_Access_Cursor) loop
        Ada.Text_IO.Put_Line (Message_Access_Vector.Element (Message_Access_Cursor).Get_Title);
  
        Message_Access_Vector.Next (Message_Access_Cursor);
     end loop;
  
  end Main;
  </code></pre>