C++ Types Not Found in C

The Class Type

The class type replaces structs as the dominant means for declaring a user-defined data type. Like a struct a class has a set of named data elements. These data elements are called its instance variables. Unlike a C struct, a class also has a set of operations, called methods, that manipulate the class's data elements. The data elements and methods that make up a class are called its members.

We will use the following class definition of an array throughout this section to illustrate the various facets of the class type:

	const int ArraySize = 12;      // default size
	
	class IntArray {
	public:
	// operations performed on arrays
	    IntArray( int size = ArraySize );
	    ~IntArray();
	    int getValue( int index );
	    void setValue( int index, int value );
	    int getSize();
	protected:
	    void checkBounds( int index );

	// internal data representation
	    int size;
	    int *data;
	};
This array class provides several services that the normal array type does not provide:

  1. The size of the array can be determined at run-time

  2. The class range-checks the array index


Data Members

  1. Like a variable declaration, but initializers are not allowed.

  2. A class object can be declared as a data member only if its class definition has already been seen. For example, the following class definition is illegal:
         class Stack {
             int topStack;
             Stack stack; // illegal--class definition not yet complete
         };
         

  3. A pointer to a class object can be declared as a data member as long as a forward declaration of the class has been seen. For example, the following class definition is legal:
         class Stack;   //forward declaration
         class Stack {
             int topStack;
             Stack *stack; // legal--a forward class declaration has been seen
         };
         
    The following is also legal because a class is considered declared as soon as its class name is seen:
         class tree_node {
             tree_node *left_child;
    	 tree_node *right_child;
         };
         


Member Functions

  1. The public member functions of a class are called the class interface.

  2. Member functions defined outside the class body must be prefixed by the class's name and two colons (::). For example:
         IntArray::IntArray( int sz ) {
             // allocate an integer array of 'size' elements.
    	 // new returns a pointer to this array or 0
    	 // 0 indicates the program has exhausted its
    	 // available memory: a generally fatal error
    	 size = sz;
    	 data = new int[size];
    
    	 for ( int ix=0; ix < sz; ix++ )
    	     data[ix] = 0;
         }
    
         void IntArray::checkBounds (int index) {
             if (index < 0) {
    	   printf("An array index is out of bounds. Its value is %d\n", index);
    	   exit(1);
    	 }
    	 if (index >= size) {
    	   printf("An array index exceeds the bounds of its array. The size\n");
    	   printf("of the array is %d but the value of the index is %d\n",
    	              size, index);
    	   exit(1);
             }
         }
    
         int IntArray::getValue (int index) {
           checkBounds(index);
           return data[index];
         }
    
         void IntArray::setValue (int index, int value) {
           checkBounds(index);
           data[index] = value;
         }
    
         int IntArray::getSize() { return size; }
    
         IntArray::~IntArray() { delete [] data; }
         

  3. Member functions have full access privilege to all the members of the class, be they public, protected, or private.


Access Privileges

  1. public: The class member is accessible from anywhere within an application. Typically only methods should be public.

  2. protected: A protected member may be inherited by a subclass and may be accessed by any of the class's methods. However, it may not be accessed anywhere else in the application. Data members should typically be declared protected.

  3. private: A private member may only be accessed by the class's member functions. The member is not inherited by any subclasses.

  4. Prefer protected to private: Protected makes inheritance possible. Private kills inheritance. It is very rare that you would want a class to contain an instance variable but not want a subclass to contain the same instance variable.

  5. Class members are private by default.

  6. Information hiding: By declaring data members as protected, you hide the class's implementation from the application. Consequently, the class's implementation can be altered without requiring any alterations to the application.

  7. If desired, access to protected data members can be efficiently provided via inline accessor methods. IntArray's GetSize method is an example of an inline, accessor method.

  8. friend: The friend keyword gives an outside class access to a class's protected and private members. For example:
         class Dlist;
         class Dlnode {
           friend Dlist;
           protected:
             ...
         };
         
    The friend declaration gives Dlist access to all of Dlnode's variables and methods. You use a friend declaration to selectively give outsiders access to a class's variables/method. Typically this is done when the outsider needs to work closely with the class or even "own" the class. For example, the only place a Dlnode will presumably be used is in a Dlist so in effect the Dlist class "owns" the Dlnode class.


The Implicit this Pointer

  1. Passed as an implicit argument to every member method.

  2. this is a pointer to the object through which this method was invoked. Consequently, the following two statements are equivalent:
         int getSize() { return size; }
         int getSize() { return this->size; }
         

  3. Common uses for this