What Is a HAS_A Relationship in C++?

By Stephen R. Davis

In an example for a C++ program, suppose the class GraduateStudent includes the members of class Student and Advisor, but in a different way. By defining a data member of class Advisor, you know that a Student has all the data members of an Advisor within it.

However, you can’t say that a GraduateStudent is an Advisor — instead you say that a GraduateStudent HAS_A Advisor. What’s the difference between this and inheritance?

Use a car as an example. You could logically define a car as being a subclass of vehicle, so it inherits the properties of other vehicles. At the same time, a car has a motor. If you buy a car, you can logically assume that you are buying a motor as well.

If friends ask you to show up at a rally on Saturday with your vehicle of choice and you go in your car, they can’t complain (even if someone else shows up on a bicycle) because a car IS_A vehicle.

But, if you appear on foot carrying a motor, your friends will have reason to laugh at you because a motor is not a vehicle. A motor is missing certain critical properties that all vehicles share — such as a place to ride.

From a programming standpoint, the HAS_A relationship is just as straightforward. Consider the following:

class Vehicle {};
class Motor {};
class Car : public Vehicle
{
  public:
    Motor motor;
};
void VehicleFn(Vehicle& v);
void MotorFn(Motor& m);
int main(int nNumberofArgs, char* pszArgs[])
{
    Car car;
    VehicleFn(car);    // this is allowed
    MotorFn(car);      // this is not allowed
    MotorFn(car.motor);// this is allowed
    return 0;
}

The call VehicleFn(c) is allowed because car IS_A vehicle. The call MotorFn(car) is not because car is not a Motor, even though it contains a Motor. If the intention were to pass the Motor portion of c to the function, this must be expressed explicitly, as in the call MotorFn(car.motor).