Log in using your OpenID or your Sol Union log in account.
[Cancel]     

C++ Language Tutorial Page 7
Classes, Structures, and Unions
Ned Bingham
Previous Index Next
Classes, Structs, and Unions
     This is where C++ starts getting complicated. C++ is an object-oriented programming language, meaning that it leans heavily on the use of objects. Classes, structures, and unions are ways of defining these objects. Say you have a car object. A car has doors, windows, wheels, and an engine. A car can also move, open a door, open a window, and turn on its engine. To make this simple, lets say that the doors and windows are stored in boolean variables: true is open and false is closed. Same with the wheels and the engine: true is moving or on, and false is not moving or off. At this point, our object will look like this:
class car
{
	public:
		bool doors;
		bool windows;
		bool wheels;
		bool engine;
};
     The keyword public declares the permissions for anything declared below. Public means that anyone, anywhere can access any of the variables below it. Private means that only functions from that class can access the variables below it. Protected means that friends of this class can access the variables below it. The permissions also define the difference between a class, structure, and a union. A class's default permission is private, a union's default permission is protected, and a structure's default permission is public.
     Lets make this car do something. Objects can also have functions that have complete access to all of the variables and other functions defined by the object alongside the functions normal input/output scheme. Let's make this car turn on to start.
class car
{
	public:
		bool doors;
		bool windows;
		bool wheels;
		bool engine;
		
		void turn_on()
		{
			engine = true;
			cout << "Vroom, the engine is on\n";
		}
};
     Let's put this car into action using the dot operator.
class car
{
	public:
		bool doors;
		bool windows;
		bool wheels;
		bool engine;

		void turn_on()
		{
			engine = true;
			cout << "Vroom, the engine is on\n";
		}

		void move()
		{
			wheels = true;
			cout << "Vroom\n";
		}
};

int main()
{
	car mercedes;
	// initialize the newly created mercedes...
	mercedes.doors = false;
	mercedes.windows = false;
	mercedes.wheels = false;
	mercedes.engine = false;
	
	// turn the car on
	mercedes.turn_on();
	
	// make it go
	mercedes.move();

	return 0;
}
     objects can also have other objects as variables, for example, a door is an object, and a car is an object, but a car has a door. So lets make a new car object with this in mind.
#include <iostream.h>

struct door
{
	int door_state; // 0 is closed, 1 is open
	bool locked;
	
	void open()
	{
		if (!locked)
		{
			door_state = 1;
			cout << "Click!! The door is now open.\n";
		}
		else
		{
			cout << "The door is locked.\n";
		}
	}
	void close()
	{
		door_state = 0;
		cout << "Fwump!! The door is now closed.\n";
	}
	void lock()
	{
		locked = true;
		cout << "Click!! The door is now locked.\n";
	}
	void unlock()
	{
		locked = false;
		cout << "Click!! The door is now unlocked.\n";
	}
};

struct car
{
	door frontleft;
	door frontright;
	door backleft;
	door backright;
	door trunk;
};

int main()
{
        car mercedes;
	mercedes.frontleft.locked = false;
	mercedes.frontleft.door_state = 0;
	
	mercedes.frontleft.open();
	mercedes.frontleft.close();
	mercedes.frontleft.lock();
	mercedes.frontleft.open();
	mercedes.frontleft.unlock();
	mercedes.frontleft.open();
	mercedes.frontleft.close();
	return 0;
}
     As you can see, to access variables and functions from objects in objects, just cascade the dot operator.
     You may also define functions outside the class to tidy up. To do this, just put the prototype of the function in the class definition, telling the class that there is another function that it can use, then you define the functions someplace else. Here is a simple example:
class car
{
        void drive();
};

void car::drive()
{
}
     In this example, the syntax "car::drive" specifies that the function "drive" belongs to the car class.
     Making a structure, class, or union is just like making a new variable type. Imagine you are actually defining the double variable type. Let's also say the you wanted to have two integer variables, one for the whole number, and one for the decimal. Then, you have made a structure with two variables, whole and decimal. Declaring an instance of this structure is just like declaring an instance of the double variable type.
     When you define a class, structure, or union, you may not initialize the variables you declare in the class until you make an instance of it, or you have a constructor. A constructor is a function that belongs to a class that initializes all of the variables in that class when an instance of that class is created. It has the same name as the class itself and no return type.
     Of course, C++ being C++, if you define a constructor, you have to define a destructor also, because it will assume you have defined one and won't call the default destructor. Destructors are just like constructors, except that they have a tilda (~) in front of the function name, and they are called when the instance of the class is being destroyed (most of the time at the end of the program). Here is an example of both constructors and destructors.
struct car
{
        car();
        ~car();
        bool door;
};

car::car()
{
        door = false;
}

car::~car()
{
        door = false;
}

int main()
{
        car mercedes;
        cout << mercedes.door << "\n";
}
OR
struct car
{
        car()
        {
                door = false;
        }
        ~car()
        {
                door = false;
        }
        bool door;
};

int main()
{
        car mercedes;
        cout << mercedes.door << "\n";
}