| User-Defined types
Pre-defined types are often not enough for programming real
life situations, therefore, there is absolutely a need for
programmers to define their own types. For example, we can define
a student type, or a teacher type for a school, an employee and
employer type for a company. You can never do that with those int,
double, long, and float, right?
And the easiest way to define a type in C++ is through the
typedef command, it is often used to abbreviate the syntax of a
specific type. For example,
typedef double db;
would abbreviate double to db. So when you want to declare a
double later in the program you can use
db mydouble;
instead of
double mydouble;
Structures:
Okay now let’s get on to some really useful user defined
types, one of them is struct. To explain what a struct is, let’s
look at an example again:
I want to create a database for the student profiles in a
school. Each profile includes name, address, age, sex, phone
number. How would you approach that?
Yes, you might have thought of using arrays, but each array can
only hold one type of data. Address and name should be strings,
sex can be a character, age and phone numbers are numbers, they
can’t be put into one single array. Use more arrays? Well let’s
look at a more efficient way to handle this.
struct student {
char name[30];
char address[100];
int age;
char sex;
long phonenum;
}; // the semi-colon is important
We’ve just created a new type, student. How does it work?
…
student this_student; //declare this_student as a student type
cout << "Name of the student: ";
cin >> this_student.name; //access the name element in
this_student with dot notation
cout << "Address of the student: ";
cin >> this_student.address;
cout << "Age of student: ";
cin >> this_student.age;
cout << "Gender of student: ";
cin >> this_student.sex;
cout >> "Phone number: ";
cin >> this_student.phonenum;
As you can see, any element from the struct can be accessed
with dot notation. Therefore, one single array of the user-defined
type student should be enough to store every data you want from a
student. For example:
student profile[100]
profile[0].name = "Bob";
profile[0].age = 14;
….
profile[90].name = "Joe";
profile[90].sex = ‘m’;
struct Constructors:
What is a constructor? It’s a member function that is
automatically called when a variable of a specific type is
declared. It assigns a default value to that variable, just like
how you assign default values to function parameters.
The syntax for a struct constructor is:
struct name::constructor name(parameters)
: initializer
{
statements
}
example:
student::student()
: name("unknown"), address("unknown"),
age(-1), sex(‘u’), phonenum(-1) //defaults
{
} //no semi-colon this time
However there’s one more step to do, put the constructor name
student() inside your struct, like this:
struct student {
student();
//like this
char name[30];
char address[100];
int age;
char sex;
long phonenum;
};
So, now when student this_student; is declared, all the
elements in this_student are assigned the default values, until
someone makes change to them.
Classes:
Now, we can go on to a bigger user defined
type, class. The use
of classes is a key feature of OOP (object-oriented programming).
Classes are similar to structs, but are
different in the way things are handled.
CLASS STRUCTURE
First, classes are usually
comprised of three files: the client file (.cpp, where
you’ve been doing all your coding), the interface (or
header) file (.h, where all your function headers and prototypes
are), and the implementation file (another .cpp, where all
the heavy duty action occurs).
Here is an example:
Say
you’re withdrawing money from an ATM:
PUBLIC AND PRIVATE
Second, when you want to
declare certain objects in classes, you can classify them as
either public or private.
You cannot do this in structs.
By default, all objects in classes are private.
(In structs, everything by default is public.)
For example, in a struct, you would see:
struct PERSONAL_INFO {
string NAME;
long SSN;
int AGE;
}
While in a class you would
see:
class
PERSONAL_INFO {
public:
string NAME;
int AGE;
private:
long SSN;
}
One helpful tip:
Make all your functions public and your data private.
It is easier this way, and your program is less likely to
fumble upon compilation.
If you want to declare an
object of a class type, just declare it the same way you would
declare an int or a string. For
example:
int jars_ketchup;
This defines the number of jars of ketchup.
CUSTOMER
Bob;
This defines what a customer named Bob wants to eat.
ACCESSING CLASS MEMBER
FUNCTIONS AND ASSIGNING VARIABLES
Ok, so now we have our objects
and declarations down pat (hopefully).
So now what? Basically,
the one thing that makes classes so unique (and sometimes
difficult to understand) is the class functions.
See that hot dog example above?
The Order() is what allows the class to work, and is what
makes the program do it’s job. So how do you access a class member function?
We’ll use a special method called dot notation:
Bob.Order()
= 2;
This defines what Bob the
customer wants to order, in terms of hot dogs.
Notice how there is a dot between Bob and Order().
That is how you access a class member function.
Just remember the simple formula:
object .
function() = variable;
Oh yeah, that’s how you
assign variables to objects as well.
CONSTRUCTORS AND DECONSTRUCTORS
One important rule in writing
classes is that they should always include a constructor and a
deconstructor. Constructors and deconstructors act as functions:
constructors set default values and declare any variables
in the class, while deconstructors erase any values used or
manipulated by the constructor, thus freeing up important memory
space. Think of it
this way: you feed a
baby and he makes a mess of the dinner table (the constructor).
Therefore, you need a mop to clean it up (the deconstructor).
Anyways, this is how you make
a constructor outside the class definition:
void CUSTOMER::CUSTOMER()
{
...(place code here)...
}
You will start with a void
type (mainly because constructors and deconstructors never
return values), followed by the name of the class, two colons, and
the name of the constructor. The constructor and class usually have the same name, for
simplicity purposes.
Inside the class
definition, the constructor takes on several different
appearances. The
first is the default constructor.
It will look like this:
CUSTOMER();
The default constructor has no
parameters. If you
don’t have other constructors with the same name, CUSTOMER()
will be called as long as you invoke it with one parameter, like
CUSTOMER(9);
or
CUSTOMER(relish);
Because you did not specify
what type this constructor should take in, it will, by default,
accept all variable types you give it.
However, if you specify a type
for the constructor, it will no longer be able to accept all
variable types. For example, if you have this constructor inside your class
definition:
CUSTOMER(int num_hotdogs);
You will only be able to
accept function calls that have integer variables, nothing else
(kind of like function headers).
Of course, you’re not just limited to int.
You can also do:
CUSTOMER(string condiments);
CUSTOMER(double
payment, char sales, int num_hotdogs);
And such.
In addition, you can have more than one constructor of the
same name inside a class definition, if these constructors take
different parameters.
class
CUSTOMER {
CUSTOMER();
CUSTOMER(string
condiments);
CUSTOMER(double
payment, char sales, int num_hotdogs);
}
Neat, huh?
Destructors are simpler to
make. All you need is a tilde (~) in front of the constructor’s
name, and you’re all set. Just
place your deconstructor under your list of constructors inside
the class definition.
class
CUSTOMER
CUSTOMER();
CUSTOMER(string
condiments);
CUSTOMER(double
payment, char sales, int num_hotdogs);
~CUSTOMER();
}
OTHER MEMBER FUNCTIONS
But wait, there are also three
other types of member functions yet to be discussed!
The accessor, modifier, and assignment
functions all help to make the class complete.
Accessor functions are
functions that access information from the implementation file of
the class program. Here,
nothing is changed, only viewed and verified.
Accessor functions make great password checkers!
double get_balance(string payment)
const;
Accessor functions are
declared with a variable type, followed by a variable name, then
the parameters, and a const.
It looks like a regular function header, but the difference
is in the const. It
prevents the data from being changed or erased, thus allowing the
accessor function to only display info and not change the info.
Modifier functions
change the info allocated in your program’s memory and return
values as well. They
look just like regular function headers, and are placed within the
class definition.
Assignment
functions take
the parameters the user has given and assigns (or reassigns)
values to another parameter.
NEXT |