Introduction to Classes |
|
Whether using C++ built-in data types or redefinitions, so far all of our variables were declared with simple data types, also called primitive types. This made is easy to recognize that, for example, the number of fingers of a hand could be represented with a simple natural number, or that a simple word made of a group of alphabetical characters could be used to name a hand. If some cases, you may want a group of values to be considered as one entity to represent an object. For example, you may want to use a single data type to represent a hand. C++ allows you to use one or more data types, group them as one, to create a new data type as you see fit. This technique of grouping different values is referred to as a class. C++ offers three techniques of defining a new data type: a structure, a class, and a union. These are also referred to as composite data types.
A structure is one or a group of variables considered as a (custom) data type. To create a structure, use the struct keyword, followed by a name for the object, at least followed by a semi-colon. Therefore, fundamentally, a structure can be created as: struct SomeName; The struct keyword is required. The name of the structure follows the same rules we reviewed for C++ names. A structure created using the above formula is referred to as an empty structure. Here is an example of a program that contains a structure: #include <iostream> using namespace std; struct Hand; int main() { return 0; } We mentioned that the idea of having a composite type is to use at least one known data type to create a new type. To do this, before the semi-colon of the structure, type an opening curly bracket "{" and a closing curly bracket "}". This would be done as follows: #include <iostream> using namespace std; struct Hand{ }; int main() { return 0; } The section between the curly brackets is referred to as the body of the structure. Inside of this body, you can declare at least one variable that would be used to define the structure. The variable must be declared complete with a known data type, a name and the ending semi-colon. Here is an example: #include <iostream> using namespace std; struct Hand{ int numberOfFingers; }; int main() { return 0; } Any variable you declare within the body of the structure is referred to as a member of that structure. For example, a variable such as NumberOfStudents is referred to as a member variable of the Hand structure. The body of the structure doesn't have to be written on the same line with a structure. In fact, to make your code easier to read, you can spread the body of the structure and its members on different lines. Based on this, the above code could have been written as: #include <iostream> using namespace std; struct Hand{ int numberOfFingers; }; int main() { return 0; } or as: #include <iostream> using namespace std; struct Hand { int numberOfFingers; }; int main() { return 0; }
Besides the structure, C++ provides a second way to create a custom data type. This is done using the exact same techniques as the structure except that you use the class keyword. Based on this, the above program can also be written as follows: #include <iostream> using namespace std; class Hand { int numberOfFingers; }; int main() { return 0; } Just as you can have an empty structure, you can also have an empty class: #include <iostream> using namespace std; class Hand; int main() { return 0; } In fact, every rule we reviewed for the structure (C++ naming rules, the body, the member variables, the curly brackets) also applies to the class. In the next sections, we will see that there is only one detail that sets the structure and the class apart. |
|
From now on, we will use the word "class" (non-bold) interchangeably to refer to either the structure or the class. When we explicitly mean a structure, we will write struct (bold) and when we explicitly designate a class, we will write class (bold). |
Object Creation and Access |
Introduction |
After creating a class, you can use it in your program as a normal data type. Just as done for built-in C++ data types, you can first declare a variable of the class. Here is an example: #include <iostream> using namespace std; struct Hand { int numberOfFingers; }; int main() { Hand human; return 0; } When you declare a variable of a class, you are said to create an Instance of the class. This means that the variable you declare is an instance of the class. In the same way, a variable you declare is called an object. It is important to understand the difference between a class and an object: A class is the list of characteristics that can be used to describe an object. An object is the result of describing something using the characteristics defined in a class. As seen above, you can declare a variable using a class. You can also declare a variable using any of the data types we have used in the previous lessons. In fact, in Lesson 3, we saw that you could declare a global variable outside of any function. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Hand { int numberOfFingers; }; int Hand; int main( int argc, char * argv[] ) { Hand human; return 0; } With this example, our program has two variables with the name of one variable being the same as the name of a class. When you declare a Hand variable in main(), as done above, and if you try compiling the program, the compiler would not know what Hand is being accessed in main() and thus would produce an error. If you declare a variable that holds a name similar to that of an existing class, when creating an instance of the class, you must specify to the compiler that the new variable is based on the class and has nothing to do with the other variable. To specify this, start the class' declaration with the class or struct keyword. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Hand { int numberOfFingers; }; int Hand; int main( int argc, char * argv[] ) { struct Hand human; return 0; } This time, the program will compile fine. |
Global Objects |
Just as reviewed for variables of primitive types, if you create an object inside of a function, which is referred to as a local declaration, the object can be accessed only from that function. If you want an object to be accessible to more than one function, you can declare it outside of any function. This is a global declaration. To proceed, you would use the same approach as the global declaration of a primitive type. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Foot { int numberOfToes; }; Foot animal; int main( int argc, char * argv[] ) { struct Foot human; return 0; } Once again, it is important to know that the compiler works from top-down. If you declare a variable globally, it can be "seen" only by functions under it. Based on this, in the above example, you can access the animal variable from main(). Consider the following: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Foot { int numberOfFingers; }; Foot animal; int main( int argc, char * argv[] ) { struct Foot human; return 0; } Foot bird; In this case, you can access animal from main() but you cannot access bird from main(). |
Access to a Member of a Class |
After declaring a variable based on a class, you can access its member variables, outside of the class, either to change their value or to retrieve the values they hold. To access the member of a class outside of the class, after declaring it, type the name of the variable, followed by a period, and followed by the name of the member you want to access. For example, to access the NumberOfFingers member variable of a class called Hand using its object instance called human, you would write: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Hand { int numberOfFingers; }; int Hand; int main( int argc, char * argv[] ) { struct Hand human ; human.numberOfFingers; return 0; } It is important to know that you cannot access a member variable while declaring a variable of the class. For example, the following code will not work: Hand human.NumberOfFingers; You must first declare the variable followed by its semi-colon. Then access the member variable. After accessing a member of a class, one of the operations you can perform would consist of assigning it a variable, which is referred to as initializing it. In C++, a member of a class cannot be initialized inside of the class. The member would be initialized outside of the class. Here is an example that assigns a value to a member variable of a class: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Hand { int numberOfFingers; }; int Hand; int main( int argc, char * argv[] ) { struct Hand human ; human.NumberOfFingers = 5; return 0; } In the same way, you can use the period operator to access the member variable of a class and retrieve its value. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Hand { int numberOfFingers; }; int Hand; int main( int argc, char * argv[] ) { struct Hand human ; Hand = 4; human.numberOfFingers = 5; cout << "Hand = " << Hand << endl; cout << "Fingers = " << human.numberOfFingers; return 0; } Just as done for variables of built-in types, you can declare as many variables as you see fit in your program. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Foot { int NumberOfToes; }; int main( int argc, char * argv[] ) { Foot human; Foot animal; return 0; } You can also declare various variables on the same line, separated by commas. Here are examples: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Foot { int NumberOfToes; }; int main( int argc, char * argv[] ) { Foot human, duck, dog, hen; return 0; } |
Type-Defining a Class |
Just as you can type-define the name of a built-in data type, you can do the same for any class. As reviewed for primitive types, when doing this, remember that you are not creating a new type: you are only providing a pseudo-name for an existing class. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Hand { int numberOfFingers; }; int main( int argc, char * argv[] ) { typedef Hand BodyMember; return 0; } After type-defining a class, you can use the new name to declare a variable as if you were using the actual name of the class. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Hand { int numberOfFingers; }; int main( int argc, char * argv[] ) { typedef Hand BodyMember; BodyMember human; return 0; } Remember that you can also type-define a class' name globally, that is, outside of any function, and use it in the other functions that would need the new name: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Hand { int numberOfFingers; }; typedef Hand BodyMember; int main( int argc, char * argv[] ) { BodyMember human; return 0; } |
Class Forward Definition |
Sometimes when creating a class, you may already know the member(s) you want it to have. In some cases, you may want to first communicate the name of the class but you are not ready to list its members. C++ allows you to perform what is referred to a forward definition. In this case, you specify only the type (struct or class) and the name of the class. This allows you to do some tasks that don't require the members of the class. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Hand; typedef Hand BodyMember; // Do anything here int main( int argc, char * argv[] ) { return 0; } Once you are ready, you can then complete the class as you see fit. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Hand; typedef Hand BodyMember; // Do anything here class Hand { int numberOfFingers; }; int main( int argc, char * argv[] ) { BodyMember human; return 0; } If you use this technique, you still must define the class before you are able to use it. Consider the following code: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Hand; typedef Hand BodyMember; // Do anything here int main( int argc, char * argv[] ) { BodyMember human; return 0; } class Hand { int numberOfFingers; }; This code will not compile because, at the time the class is instantiated in main(), its definition is not known, only its emptiness, which is not enough. |
The Access Levels of a Class |
So far, to make our learning process easier, we declared only one member variable in a class. The primary reason for using a class as opposed to a built-in data type is to be able to group different characteristics used to describe the class and make it as complete as possible. This means that a class is meant to have as many members as you judge necessary. To apply this, in the body of the class, declare the necessary variables, each with a data type and a name, and each declaration ending with a semi-colon. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; }; int main( int argc, char * argv[] ) { return 0; } Once again, to access its members outside of the class, you can first declare a variable based on the class. To access a member variable, you type the class' variable name, followed by the period operator. Here is an example: #include <iostream> using namespace std; struct Car { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; }; int main() { Car vehicle; vehicle.Mileage = 42580; cout << "Car Characteristics\n"; cout << "Mileage: " << vehicle.Mileage << endl; return 0; } This would produce: Car Characteristics Mileage: 42580 A common object in real life is visibly made of two categories of parts: those you can see or touch and those you do not have access to. The parts you can see or touch are considered visible or accessible. In C++, such parts are referred to as public. Those you cannot see or touch are considered hidden. In C++, such parts are referred to as private. Like objects in real life, a class is made of sections that the other parts or other objects cannot “see” and those the other objects can access. The other objects of of the program are sometimes referred to as the clients of the object. The parts the client of an object can touch in a class are considered public and the others are private. When creating a class, you will define which items are public and which ones are private. The items that are public are created in a section that starts with the public keyword followed by a semi-colon. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { public: int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; }; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Mileage = 42580; cout << "Car Characteristics\n"; cout << "Mileage: " << vehicle.Mileage; return 0; } In the same way, the hidden parts are in a section that starts with the private keyword followed by a semi-colon. If you don't specify these sections, all of the members of a class are considered private. The difference between a class and a structure is that, by default, all of the members of a class are private and, by default, all of the members of a structure are public. That is how it works if you don't create your own public and private sections. For example, the following program will not compile: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Car { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; }; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Mileage = 42580; cout << "Car Characteristics\n"; cout << "Mileage: " << vehicle.Mileage; return 0; } The reason is that the Mileage member variable that belongs to a class type is private and therefore cannot be accessed from main(). To resume, when creating your class, you can specify the necessary access levels using the public: and private: sections. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { public: int Year; unsigned NumberOfDoors; bool HasAirCondition; private: char DrivingCondition; short TypeOfTransmission; char Color; public: long Mileage; }; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Mileage = 42580; cout << "Car Characteristics\n"; cout << "Mileage: " << vehicle.Mileage; return 0; } As you can see from this class, there are no rules as to the number of public or private sections you can have in a class. There are no rules on the order of the access levels: you can create a public or a private section anywhere in the class, just remember that any member under an access level follows the rules of that access. The fact that you use different public sections does not by any means provide different public levels to the variables. A variable declared as public in one public section has the same public level of access as any other variable that is declared in another public section. |
Object Initialization |
Initializing Each Member of a Class |
Just as variables of primitive types, an object declared from a class can also be initialized. There are various techniques you can use: initializing individual members or initializing the class as a whole. To initialize a member of a class, access it and assign it an appropriate value using the rules of C++:
Here are examples: |
#ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { char Make[40]; char Model[40]; int Year; unsigned NumberOfDoors; bool HasAirCondition; long Mileage; }; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Mileage = 42885; strcpy(vehicle.Model, "Escort"); vehicle.NumberOfDoors = 4; strcpy(vehicle.Make, "Ford"); vehicle.HasAirCondition = true; vehicle.Year = 2000; cout << "Car Auctions - Vehicle Characteristics"; cout << "\nYear: " << vehicle.Year; cout << "\nMileage: " << vehicle.Mileage; cout << "\nMake: " << vehicle.Make; cout << "\nModel: " << vehicle.Model; cout << "\nDoors: " << vehicle.NumberOfDoors; cout << "\nHas A/C: " << vehicle.HasAirCondition; return 0; }
This would produce:
Car Auctions - Vehicle Characteristics Year: 2000 Mileage: 42885 Make: Ford Model: Escort Doors: 4 Has A/C: 0
Initializing an Object as a Whole |
You can also initialize an object as a variable. This time, type the name of the variable followed by the assignment operator, followed by the desired values of the variables listed between an opening and a closing curly brackets. Here are the rules you must follow:
Here is an example: |
#ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { char Make[40]; char Model[40]; int Year; unsigned NumberOfDoors; bool HasAirCondition; long Mileage; }; int main( int argc, char * argv[] ) { Car SUV = { "Toyota", "4-Runner", 1998, 5, true, 57922 }; cout << "Car Auctions - Vehicle Characteristics"; cout << "\nYear: " << SUV.Year; cout << "\nMileage: " << SUV.Mileage; cout << "\nMake: " << SUV.Make; cout << "\nModel: " << SUV.Model; cout << "\nDoors: " << SUV.NumberOfDoors; cout << "\nHas A/C: " << SUV.HasAirCondition; return 0; } This would produce: Car Auctions - Vehicle Characteristics Year: 1998 Mileage: 57922 Make: Toyota Model: 4-Runner Doors: 5 Has A/C: 1 |
Static Member Variables |
A class can have static member variables. To declare such a variable, precede it with the static keyword. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { string Make; string Model; int Year; unsigned NumberOfDoors; long Mileage; static int CarsCount; }; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Year = 1998; vehicle.Mileage = 57922; vehicle.Make = "Toyota"; vehicle.Model = "4-Runner"; vehicle.NumberOfDoors = 5; cout << "Car Auctions - Vehicle Characteristics"; cout << "\nYear: " << vehicle.Year; cout << "\nMileage: " << vehicle.Mileage; cout << "\nMake: " << vehicle.Make; cout << "\nModel: " << vehicle.Model; cout << "\nDoors: " << vehicle.NumberOfDoors; return 0; } When you declare a member variable as static and when the application starts, the compiler creates a copy of that member. This member would be maintained by the compiler while the program is running. If you declare an instance of a class, like the above vehicle variable, the static member is not part of the (vehicle) object: the compiler creates and maintains the CarsCount member, whether you use it or not, whether you declare a Car variable or not. After creating a class that contains a static member variable, if you intend to use that member, you should (in fact must) first initialize it with the value you want it to hold. Because a static member variable doesn't belong to an object, it must be initialized at file cope, by the class itself and not one of its instances. To initialize a static member variable, outside of the class, enter its data type, followed by the name of the class, followed by the access operator "::", followed by the name of the member variable, followed by the assignment operator, and followed by a value. Like any other member variable, you can assign any appropriate value to a static member: you decide what value you want it to have. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { string Make; string Model; int Year; unsigned NumberOfDoors; long Mileage; static int CarsCount; }; int Car::CarsCount = 0; int main( int argc, char * argv[] ) { Car vehicle; return 0; } After creating and initializing a static member variable, to access it outside of the class, you must qualify it with the name of the class itself and not a variable of that class. Here are two examples: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { string Make; string Model; int Year; unsigned NumberOfDoors; long Mileage; static int CarsCount; static string ApplicationTitle; }; int Car::CarsCount = 1; string Car::ApplicationTitle = "Four-Corner Car Auctions"; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Year = 1998; vehicle.Mileage = 57922; vehicle.Make = "Toyota"; vehicle.Model = "4-Runner"; vehicle.NumberOfDoors = 5; cout << Car::ApplicationTitle; cout << "\n - Vehicle Characteristics -"; cout << "\nYear: " << vehicle.Year; cout << "\nMileage: " << vehicle.Mileage; cout << "\nMake: " << vehicle.Make; cout << "\nModel: " << vehicle.Model; cout << "\nDoors: " << vehicle.NumberOfDoors; cout << "\nCount: " << Car::CarsCount; return 0; } This would produce: Four-Corner Car Auctions - Vehicle Characteristics - Year: 1998 Mileage: 57922 Make: Toyota Model: 4-Runner Doors: 5 Count: 1 Always remember that a static member doesn't belong to a particular object, in this case vehicle. Therefore, to access it, you use the name of the class with the "::" operator. With this rule in mind, you can assign the value of a static member to a variable of the program. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { string Make; string Model; int Year; unsigned NumberOfDoors; long Mileage; static int CarsCount; static string ApplicationTitle; }; int Car::CarsCount = 1; string Car::ApplicationTitle = " Four-Corner Car Auctions"; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Year = 1998; vehicle.Mileage = 57922; vehicle.Make = "Toyota"; vehicle.Model = "4-Runner"; vehicle.NumberOfDoors = 5; int numberOfCars = Car::CarsCount; cout << Car::ApplicationTitle; cout << "\n - Vehicle Characteristics -"; cout << "\nYear: " << vehicle.Year; cout << "\nMileage: " << vehicle.Mileage; cout << "\nMake: " << vehicle.Make; cout << "\nModel: " << vehicle.Model; cout << "\nDoors: " << vehicle.NumberOfDoors; cout << "\nCount: " << numberOfCars << endl; return 0; } You can decrement or increment it as you wish: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; struct Car { string Make; string Model; int Year; unsigned NumberOfDoors; long Mileage; static int CarsCount; static string ApplicationTitle; }; int Car::CarsCount = 1; string Car::ApplicationTitle = " Four-Corner Car Auctions"; int main( int argc, char * argv[] ) { Car vehicle; vehicle.Year = 1998; vehicle.Mileage = 57922; vehicle.Make = "Toyota"; vehicle.Model = "4-Runner"; vehicle.NumberOfDoors = 5; cout << Car::ApplicationTitle; cout << "\n - Vehicle Characteristics -"; cout << "\nYear: " << vehicle.Year; cout << "\nMileage: " << vehicle.Mileage; cout << "\nMake: " << vehicle.Make; cout << "\nModel: " << vehicle.Model; cout << "\nDoors: " << vehicle.NumberOfDoors; cout << "\nCount: " << Car::CarsCount << endl; Car family; family.Mileage = 42885; family.Model = "Escort"; family.NumberOfDoors = 4; family.Make = "Ford"; family.Year = 2000; Car::CarsCount++; cout << "\n - Vehicle Characteristics -"; cout << "\nYear: " << family.Year; cout << "\nMileage: " << family.Mileage; cout << "\nMake: " << family.Make; cout << "\nModel: " << family.Model; cout << "\nDoors: " << family.NumberOfDoors; cout << "\nCount: " << Car::CarsCount << endl; return 0; } This would produce: Four-Corner Car Auctions - Vehicle Characteristics - Year: 1998 Mileage: 57922 Make: Toyota Model: 4-Runner Doors: 5 Count: 1 - Vehicle Characteristics - Year: 2000 Mileage: 42885 Make: Ford Model: Escort Doors: 4 Count: 2 |
Other Techniques of Creating an Object |
Classic C Styles |
So far, to declare a variable of a class, we did this in the main() function. C++ supports another technique. You can declare a class when creating it. To do this, type the name of the class' variable between the closing curly bracket and the semi-colon. Here is an example: #include <iostream> using namespace std; struct Car { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; }vehicle; int main() { vehicle.Mileage = 42580; vehicle.NumberOfDoors = 4; vehicle.DrivingCondition = 'G'; vehicle.Year = 2000; cout << "Car Characteristics\n"; cout << "Year: " << vehicle.Year << endl; cout << "Condition: " << vehicle.DrivingCondition << endl; cout << "Mileage: " << vehicle.Mileage << endl; cout << "Doors: " << vehicle.NumberOfDoors << endl; return 0; } Just like you would declare more than one variable of a class, you can declare many class instances using this technique, separating them with commas. Here are examples: #include <iostream> using namespace std; struct Car { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; }Sport, SUV, Bus; int main() { SUV.Mileage = 28446; SUV.NumberOfDoors = 5; SUV.DrivingCondition = 'D'; SUV.Year = 2002; Sport.Mileage = 68208; Sport.NumberOfDoors = 2; Sport.DrivingCondition = 'E'; Sport.Year = 1998; cout << "First Car Characteristics\n"; cout << "Year: " << SUV.Year << endl; cout << "Condition: " << SUV.DrivingCondition << endl; cout << "Mileage: " << SUV.Mileage << endl; cout << "Doors: " << SUV.NumberOfDoors << endl; cout << "\nSecond Car Characteristics\n"; cout << "Year: " << Sport.Year << endl; cout << "Condition: " << Sport.DrivingCondition << endl; cout << "Mileage: " << Sport.Mileage << endl; cout << "Doors: " << Sport.NumberOfDoors << endl; return 0; } This would produce: First Car Characteristics Year: 2002 Condition: D Mileage: 28446 Doors: 5 Second Car Characteristics Year: 1998 Condition: E Mileage: 68208 Doors: 2 C programmers use another technique of creating classes. It consists of using the typedef keyword, which means you would define a type but set the actual name of the class between the closing curly bracket and the semi-colon. Here is an example of using that technique: #include <iostream> using namespace std; typedef struct MobileEngine { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; }Car; int main() { return 0; } Optionally, you can type a pseudo-name for the class on the first line. Here is an example: #include <iostream> using namespace std; typedef struct _car { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; } Car; int main() { return 0; } After creating the class, the Car name is a class, not a variable. Therefore, when you want to use the object, you must and can declare an instance of the class using either the _car or the Car name. Here are examples: |
#include <iostream> using namespace std; typedef class _car { int Year; unsigned NumberOfDoors; long Mileage; char DrivingCondition; } Car; int main() { _car vehicle; Car mobile; return 0; }
References |
As done for variables of primitive types, you can create a reference to a class using a declared variable. The same rule applies: the object that is used as a reference must have previously been initialized. Here is an example: #ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Car { public: char Make[40]; char Model[40]; int Year; unsigned NumberOfDoors; bool HasAirCondition; long Mileage; }; int main( int argc, char * argv[] ) { Car vehicle = { "Toyota", "4-Runner", 1998, 5, true, 57922 }; Car &SUV = vehicle; cout << "Car Auctions - Vehicle Characteristics"; cout << "\nYear: " << SUV.Year; cout << "\nMileage: " << SUV.Mileage; cout << "\nMake: " << SUV.Make; cout << "\nModel: " << SUV.Model; cout << "\nDoors: " << SUV.NumberOfDoors; cout << "\nHas A/C: " << SUV.HasAirCondition; return 0; } |
Constant Objects |
Just as you can create a constant of a built-in data type, you can also create a constant using a composite type. Always remember that the constant refers to a value that doesn't change and the constant value must be initialized with a known or already defined value. Here is an example: |
#ifdef __BORLANDC__ #pragma argsused #endif #include <iostream> using namespace std; class Car { public: int Year; unsigned NumberOfDoors; bool HasAirCondition; private: char DrivingCondition; short TypeOfTransmission; char Color; public: long Mileage; }; int main( int argc, char * argv[] ) { Car vehicle, sportCar; vehicle.Mileage = 28446; vehicle.NumberOfDoors = 5; vehicle.Year = 2002; cout << "Vehicle Characteristics\n"; cout << "Year: " << vehicle.Year << endl; cout << "Mileage: " << vehicle.Mileage << endl; cout << "Doors: " << vehicle.NumberOfDoors << endl; sportCar.Mileage = 28446; sportCar.Year = 2002; const Car mobile = vehicle; cout << "\nSport Car Characteristics\n"; cout << "Year: " << sportCar.Year << endl; cout << "Mileage: " << sportCar.Mileage << endl; cout << "\nMobile Characteristics\n"; cout << "Year: " << mobile.Year << endl; cout << "Mileage: " << mobile.Mileage << endl; cout << "Doors: " << mobile.NumberOfDoors << endl; return 0; }
This would produce:
Vehicle Characteristics Year: 2002 Mileage: 28446 Doors: 5 Sport Car Characteristics Year: 2002 Mileage: 28446 Mobile Characteristics Year: 2002 Mileage: 28446 Doors: 5
Unions |
Introduction |
Like a structure, a union is created from combining other variables. To create a union, use the union keyword following the same syntax applied for a class, like this: union SomeName {}; Like a structure, the members of a union are listed in its body. For example, to create a union that represents a student, you would type: union Student { char FullName[32]; int Age; float AvgGrade; }; Once the union is defined, you can declare it and use its members: #include <iostream> using namespace std; union Student { int Age; double AvgGrade; }; int main() { Student Std; Std.Age = 12; cout << "Student Age = " << Std.Age; return 0; } This would produce: Student Age = 12 |
Using a Union |
When creating a struct or a class, each variable, treated as its own entity, occupies its assigned amount of space in memory. This is different with unions. All of the members of a union share the same memory space. After declaring a union object, instead of allocating memory for each member variable, the compiler assigns an amount of memory equal to the largest variable. Therefore, if you define a union that would represent a Student object as the above, the compiler would assign the same memory space to all members; and the compiler would find out which member needs the largest space, in this case that would be the double variable because a double variable occupies 8 Bytes. Consequently, a union can store only the value of only (excuse the repetition) one of its members at a time: you cannot simultaneously access the values of all members, at the same time (another repetition). If you initialize all of the members of a union at the same time, the result is unreliable; since all members are using the same memory space, that space cannot accommodate all member values at the same time. The following version of our program produces such an unreliable result: #include <iostream> using namespace std; union Student { char Gender; int Age; float AvgGrade; double GradeSum; }; int main() { Student Std; Std.Gender = 'F'; Std.Age = 14; Std.AvgGrade = 14.50; Std.GradeSum = 210; cout << "Characteristics of this student"; cout << "\n\tGender = " << Std.Gender; cout << "\n\tAge = " << Std.Age; cout << "\n\tAverage = " << Std.AvgGrade; cout << "\n\tTotal = " << Std.GradeSum; return 0; } This would produce: Characteristics of this student Gender = Age = 0 Average = 0 Total = 210 As you can see, you should not substitute unions and structures. You should use a union when you can/must store any kind of variable in the same location, when variables sharing the same memory location is not an issue (or a danger). Avoid using unions in highly accessed and intensive value exchanges, such as calculations or data records. A union is usually created inside of another object. Because all members of a union share the same memory location, a union is sometimes used to identify one value to use among many. Consider the following example: #include <iostream> using namespace std; union HighSchool { int RegistrationStatus; double Salary; }; int main() { return 0; } In this case, two different, obviously unrelated variables are declared. The idea here is that only one of them would be used in the program, but which one. Imagine that you are starting a program for a high school. If the person whose information is being entered in the application is a student, then you need to specify his or her registration status, the eventual values would specify Registered, Pending, or Excluded. On the other hand, if the person whose information is being entered is a staff member such as a teacher, then the registration status is irrelevant but you may want to enter his or her salary, a piece of information that is irrelevant for a student. This example shows that, for one particular record being created, only one of these two values would be considered and the other would not apply. |
|
||
Previous | Copyright © 1998-2005 FunctionX, Inc. | Next |
|