7.4 DECLARATION OF POINTER TYPES IN C


7.4 DECLARATION OF POINTER TYPES IN C++

One of the most notable differences between C++ and Java is that the former has pointers and the latter does not.[4]

For any type T in C++, T* is of the type pointer to an object of type T. A variable of type T* can hold the address of an object of type T. For example,

   int i = 100;   int* p = &i;                    //(A) 

where & is the address operator. The declaration in line (A) makes p a pointer of type int*.

A fundamental operation on a pointer is dereferencing, that in effect retrieves the object pointed to by the pointer. The operation of dereferencing, also called indirection, is carried out by applying the operator * to a pointer. For example, we could dereference the pointer p defined above by

     int a = *p;                                                //(B) 

One must bear in mind the two different semantic roles played by the symbol * in the context of pointers. In a declaration of a pointer variable, as in line (A) above, the symbol * tells the compiler that the identifier p will be used to hold the address of an int variable. But, when used as in line (B) above, the symbol * is an operator that when applied to a pointer causes it to be dereferenced.

Pointers and, as we will be discussed in the next section, arrays of pointers play an extremely important role in C++ programming. While all of the usual reasons for using pointers in C also apply to C++,[5] here are three more that are particularly relevant to C++:

Polymorphism:Object-oriented programming derives much of its power and utility from polymorphism, a concept presented briefly in Chapter 3 and explained more fully in Chapter 15. Polymorphism works in C++ only when objects are manipulated through pointers and references.

Interleaved Classes:Unlike Java, the order in which classes are presented to a C++ compiler is important. To explain, suppose class X has a data member of type W. When the compiler gets to that data member in X, it had better already have seen the class W. But what does one do when we have two classes, say, W and X, with W containing a data member of type X and X containing a data member of type W-a not uncommon situation on OO? To deal with such situations, C++ allows us to just declare a class name without having to provide its definition. So we could just declare X as a class name and not give its definition, then define class W, and thenproceed to define X. But this can only be done if the reference to the incompletely defined X in W is via a pointer. This is explained in greater detail in Chapter 11.

The Need for a "null" Object:In OO programming there often arises a need to "null" out an object. To elaborate, let's say that a class type variable is holding a reference of some kind to an object. At a later point in the program, the program conditions may require that we "zero out" or "nullify" the value of the variable. In Java, this can be done conveniently by changing the value of the variable to the null object reference. The only way to achieve the same effect in C++ is by using the notion of the null pointer that is denoted by the symbol 0. In C++, when the value of a pointer variable pointing to a class type object is set to 0, we can be certain that it is not pointing to any particular location in the memory.

While the first two of the three reasons given above will be discussed in greater detail elsewhere in the book, in the rest of this section we will provide examples of what we mean by "nulling" an object and why pointers are useful for that purpose. Let's say we have created a Person class by

    class Person {         string name;         string address;         // many more    public:    Person( string theName, string theAddress ) {        name = theName;        address = theAddress;    } }; 

Now suppose inside an object-oriented program we make a new Person as follows:

      Person* ptr = new Person( "John Doe", "Main Street USA" ); 

If at some later place in the program, we wish to "zero out" or "nullify" this new person, all we have to do is to say

    ptr = 0; 

although in actuality we would say

    delete ptr;    ptr = 0; 

The delete operator would also free up the memory occupied by the object to which ptr was pointing.[6]

An alternative would be to create the object by

     Person peson1( "John Doe", "Main Street USA" );         //C) 

which does not involve the use of pointers. Let's say that at some point we wish to "zero out" the object person1. We evidently cannot say

    person1 =0;                     // WRONG 

because that would make no sense to the compiler. We could destroy the object which is referred to by person1 by invoking the same delete operator as before:

    delete &person1;                // WRONG             //(D) 

but that would not work because the delete operator can only free up that memory which is acquired by the new operator-that is, the memory allocated on the heap. When we construct a Person object in the manner shown in line (C), the memory for the object is allocated on the stack. Therefore, invoking the delete operator, in the manner shown in line (D), will in general elicit a memory-segmentation fault message from the system.

As another example, consider

    string str( "hello" ); 

If at a later time, we wanted to "zero out" the value of str, we are not allowed to say[7]

    str = 0;                       // WRONG 

However, if we had said

      string* ptr = new string( "hello" ); 

If so needed, we'd then be able to zero out the value of ptr by simply saying

      ptr = 0; 

although we should actually say

      delete ptr;      ptr = 0; 

in order to properly deallocate the memory before nullifying the pointer.

[4]This statement sometimes elicits a retort from some programmers who say that an object reference in Java is a pointer. All we are saying here is that an object reference in Java is not directly a memory address that can be dereferenced and that you can do pointer arithmetic on.

[5]Such as getting around the limitations that are caused by the fact that a function can only return one value. By passing pointer arguments to a function and using side effects, a called function can be made to bring about multiple changes visible in the calling program even though the called function can return only one value.

[6]Memory allocation and deallocation will be discussed in detail in Chapter 8.

[7]This is a good time to mention that the often-used NULL pointer of C becomes the symbol 0 in C++. If your programming habits compel you to use NULL for a null pointer, you could use the following definition in your program:

    const int NULL = 0; 




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net