2.8. The Implicit this Reference

Up to this point, all our data members and member functions have been instance members. An instance data member has a copy of itself stored within each class object that we create. To call a member function an instance member means that the function must be invoked through an object of its class.

When an instance data member is accessed within a member function, the name of the data member serves as a placeholder. A member function does not maintain a copy of each class data member it accesses. Rather, when the member function is invoked through an actual class object, the name of the data member within the function is bound to the instance associated with the class object. This binding is accomplished through the implicit this reference.

Within an instance member function, the this reference refers to the class object through which the member function is invoked. The this reference is used internally to bind a use of a data member to the instance of that member within the class object. For example, consider the following code fragment:

private void countWords()
{
      m_sentences = new string[ m_text.Count ][];
      m_words     = new Hashtable();

      string str;
   for( int ix = 0; ix < m_text.Count; ++ix ) { ... }
}

Internally, each unqualified access of an instance data member is augmented to refer to the member through the this reference—for example,

this.m_sentences = new string[ this.m_text.Count ][];
this.m_words     = new Hashtable();

for( int ix = 0; ix < this.m_text.Count; ++ix ) { ... }

We pass the this reference to each instance member function by augmenting the function's parameter list with an additional class parameter:

private void countWords( WordCount this ){ ... }

This means that the invocation of the member function must also be rewritten internally by the compiler to reflect the internal signature. For example, when we internally write

theObj.processFile();

it is turned into

processFile( theObj );

An unqualified invocation of an instance member function, such as

public void processFile(){ countWords(); }

first has its invocation augmented by the addition of the this reference:

public void processFile( WordCount this )
       { this.countWords(); }

which is then rewritten to reflect the augmented parameter list of each function:

public void processFile( WordCount this )
       { countWords( this ); }

In some instances within a program, having access to the this reference solves an otherwise intractable problem. For example, let's say that we need to implement a doubly-linked list of strings. We'll call the class StringNode. It contains three data members:

class StringNode
{
   private StringNode back_link;
   private StringNode front_link;
   private string     text;

   public StringNode( string str ){ text = str; }
   // ...
}

We need to provide an Append() operation supporting the following usage:

StringNode node = new Node( "a node" );
// ...
node.Append( new StringNode( "also a node" ));

There are three steps to appending a StringNode object: (1) The front_link of the new node is set to the front_link of the existing node; (2) the front_link of the existing node is set to the new node; and (3) the back_link of the new node is set to the existing node:

public void Append( StringNode new_node )
{
      new_node.front_link = front_link;  // (1)
      front_link = new_node;             // (2)
      new_node.back_link = ?????         // (3)
}

Without the this reference, we have no way to directly reference the object through which Append() is invoked. We complete the implementation by assigning back_link to refer to this:

new_node.back_link = this; // (3)

If we wish, we can explicitly prefix the access of an instance member with the this reference. Some people claim that this prefix makes the code more readable; the idea is that it clearly identifies instance members within the function. Personally, I find that the presence of the this reference within a function gives the code a cluttered feel.[1]

[1] The Visual Studio code generation wizards, for example, mechanically insert an explicit instance of this.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.230.81