Click Here!
home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next


You will make use of the Vehicle class declared in How-To 3.1. If you did the example in How-To 3.1, change to the VEHICLE subdirectory and skip to step 3 in the “Steps” section that follows; otherwise, proceed to the “How It Works” section that follows.

Steps

1.  If you did not do How-To 3.1, change to your base source directory and create a new subdirectory named VEHICLE. Start your source editor and type the following code into a file named VEHICLE.H:
// vehicle.h - this file contains a class
// declaration for the vehicle type.
class Vehicle
{
public:
    enum Switch { SWITCH_ON, SWITCH_OFF } ;
    Vehicle( ) ;
    ~Vehicle( ) ;

    bool powerSwitch( Switch onOrOff ) ;
    unsigned int accelerate( unsigned int amount ) ;
    unsigned int decelerate( unsigned int amount ) ;
    bool isMoving( void ) const ;
    unsigned int getSpeed( void ) const ;
    unsigned int setSpeed( unsigned int speedIn ) ;
protected:
    bool moving ;
private:
    unsigned int speed ;
} ;

Please note that if your compiler does not support the bool data type, you can add the following line of code at the top of this header file:
enum bool { false = 0, true } ;
2.  If you did not do How-To 3.1, create a new file named VEHICLE.CPP and type the following code into that file:
// declaration of Vehicle
#include “vehicle.h”

Vehicle::Vehicle( ) :
    speed( 0 ), moving( false )
{
}

Vehicle::~Vehicle( )
{
    speed = 0;
    moving = false ;
}

bool Vehicle::powerSwitch( Switch onOrOff )
{
    bool on = false ;
    if( onOrOff == SWITCH_OFF )
    {
        speed = 0 ;
        moving = false ;
    }

    return( on ) ;
}

unsigned int Vehicle::accelerate( unsigned int amount )
{
    speed += amount ;
    moving = true ;

    return( speed ) ;
}

unsigned int Vehicle::decelerate( unsigned int amount )
{
    if( amount > speed )
        speed = 0 ;
    else
        speed -= amount ;

    moving = (speed == 0) ? false : true ;

    return( speed ) ;
}

bool Vehicle::isMoving( ) const
{
    return( moving ) ;
}

unsigned int Vehicle::getSpeed( ) const
{
    return( speed ) ;
}

unsigned int Vehicle::setSpeed( unsigned int speedIn )
{
    speed = speedIn ;
    moving = true ;

    return( speed ) ;
}

How It Works

There are two views of a class. One view is the public interface and the second is the private implementation. The interface is the contract that a class makes available to users of the class. It is the means by which a user of a class controls the state of an object. The implementation of a class is of no concern to users of a class. How an object actually alters its state should be shielded from the users of an object. There should be a clean separation of interface and implementation. This allows you to change the implementation without disturbing the interface to the users of the class.

The interface of the Vehicle class includes a constructor, destructor, and six member functions. Users of the class can only change the state of an instance of Vehicle through these six member functions. The user can not access the protected and private class members.

Each member function provides program logic to maintain the integrity of each instance of the class. This is the cornerstone of implementation—to maintain the integrity and state of each class instance. If the data members are exposed to users of the class, any instance of a class is in jeopardy. Moreover, if an instance of a class is in jeopardy, your application is in jeopardy.

The member functions accelerate, decelerate, and setSpeed are used by clients of the class to alter the state of the speed attribute. The implementation of each of these member functions should provide checks to ensure that the speed attribute is not corrupted or assigned a meaningless value. One safeguard is that the attribute is declared as an unsigned int. You have to ask yourself: “Does it make sense to have a speed of –23?” The powerSwitch member function is provided so that users of the class can start up or turn off an object. These member functions are commonly referred to as mutator functions because they alter the internal state of an object.

The remaining member functions, isMoving and getSpeed, are known as accessor member functions. These functions are provided so that users of the class can examine specified attributes of a class. You should only provide accessor functions that make sense as it might not be desirable for clients to examine every instance variable of a class. You should only return a copy of the instance variable; never return a pointer or reference to an internal variable. Otherwise, why make it private? If you return a pointer (or reference) to an internal variable, users of the class can manipulate the attribute directly. You might want to refer to How-To 1.5 concerning pointers.

As you can expect, the attributes of the class are hidden within the protected and private sections of the class declaration. The moving data member has protected visibility; this allows the class declaring it and any derived classes to access the object directly. Users of the class cannot access the data member directly; users can only access the variable through the class’s interface, if so provided. The data member speed is declared with private visibility.

Although the Vehicle class does not demonstrate it, member functions can also be declared with protected or private visibility. Your classes might require member functions that implement internal functionality to support the class’s interface. For example, you might have a private member function named meterGasoline or adjustAirMeter to support the public member function accelerate.

3.4 Implement polymorphism in C++?

Problem

I am familiar with the term polymorphism and understand its concept. I have not implemented this feature in C++ and would like to know how.

Technique

This How-To demonstrates polymorphism by providing a simple program. Polymorphism is a powerful feature that is synonymous with dynamic function binding. Polymorphism is derived from Latin and means “many (poly) forms (morph).” It is a facility whereby a member function having the same signature in a hierarchy of classes, each having a different implementation, is dynamically bound (called) at runtime based on the type of the object.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.