Академический Документы
Профессиональный Документы
Культура Документы
Classes
I. Introduction:
A class is an extended type of structure. Unlike structures, which hold data
only, classes can hold both data and functions.
An object is an instantiation of the class. i.e. class would be a type and object is
the variable.
class class_name
{
access_specifier1:
member1;
access_specifier2:
member2;
};
Example 2.1:
class Fraction
{
public:
int num, den;
};
void main()
{
Fraction x; //Declaring object of type Fraction.
cout<<“x=”<< x.num << “/” << x.den << endl;
Example 2.2:
class Fraction
{
private:
int num, den;
};
void main()
{
Fraction x;
cout<<“x=”<< x.num << “/” << x.den;
//ERROR:
//“num” and “den” are not accessible.
}
As you can see in the previous example we can’t use the private members
directly from the object name using the dot operator. That’s why we need to
declare member functions.
Notes:
- print() will print the object content to the screen. So there is no need for
return value. Also we don’t need anything from outside the object, so there
will be no parameters for this function.
- set(int,int) will take two values from outside the object and assign them
to the object members. And it will not return anything to the caller.
- convert() will convert the fraction object to float by divide the members
and return the result to the caller.
- We will just include the member function prototype inside the class
definition.
- We will write the function definition after the class definition, but we have to
prefix the class name that function belongs to and the scope operator “::”.
- If we didn’t include the class name and the scope operator it will produce
logical error.
void main()
{
Fraction x; //Declaring object of type Fraction.
x.set(2,5); //Call member function set(int,int)
x.print(); //Call member function print()
cout<<”=”<<x.convert();
//print the result returned by convert()
}
Note:
If the member function is receiving an object from the same class, the
private members can be accessed through the object’s name.
But this will not work with class object . That’s why we need to use
constructors.
Overloading constructor:
- To overload a constructor we have to define it as a member function inside
the class.
- Constructor will have the same name of the class.
- We don’t specify a return type for a constructor even void. It will be
considered as a syntax error.
- Syntax: class_name(parameters);
- We can send parameter to the constructor.
- We can have more than one constructor but they must have different
signature (i.e. different parameter types, order and number).
- We can use default arguments with the constructor.
- We can’t use a version of a constructor that we don’t define by ourselves.
- To use the overloaded constructor with parameters put the parameters inside
( ) after the object name.
Time x(12,0,0);
Time y;
Time z(12);
//ERROR:
//We don’t have a constructor that take’ll one parameter
}
Time::Time()
{
hour = min = sec = 0;
}
Time::Time(int a, int b, int c)
{
hour = a;
min = b;
sec = c;
}
Time x;
//Now in the object x : hour=min=sec=0
Time y(12);
//Now in the object y : hour=12, min=sec=0
Time z(3,30);
//Now in the object z : hour=3, min=30, sec=0
Time a(3,30,50);
//Now in the object a : hour=3, min=30, sec=50
}
Time::Time(int a, int b, int c)
{
hour = a;
min = b;
sec = c;
}
Example 2.6:
Using overloaded constructor with initializer lists and parameters
class Time
{
int hour, min, sec;
public:
Time(int =0, int b=0, int c=0);
};
void main()
{
Time x;
}
//We use initializer list for all members with parameters
Time::Time(int a, int b, int c):hour(a), min(b), sec(c)
{
}
Note:
- Although a constructor is a member function but we can’t call it by ourselves
as we do it with other member functions. It will cause a syntax error.
- The constructor is called only ONCE in the object’s lifetime.
x.Time();
//Error: We can’t call constructor by object name.
}
Time::Time(int a, int b, int c):hour(a), min(b), sec(c)
{
}
The destructor is called when the object reaches the end of its scope. If
we didn’t built our own destructor, a default destructor is used. But if we built it
with ourselves it’s called overloaded destructor.
Overloading destructor:
- To overload a destructor we have to define it as a member function inside the
class.
- Destructor will have the same name of the class with ~ sign before it.
- We don’t specify a return type for a constructor even void. It will be
considered as a syntax error.
- We can’t send parameters to the destructor. It will be considered as a syntax
error.
- Syntax: ~class_name();
- We can’t have more than one destructor.
Note:
- We have to build our own destructor when we use a dynamic allocation for a
member or more in object. This destructor will contain the delete statement
for the dynamic member.
strcpy(name, a);
cout<<name<<” is created.\n”;
}
Person :: ~Person ()
{
cout<<name<<” is deleted.\n”;
delete name;
}
When we use one class within definition of another class. i.e. when one of
the data member is an object of another class.
We have to define the inner class before using it inside the other class.
//We use initializer lists for the object data members. And
//give them the needed valused or parameters.
Log::Log():in(0,0,0), out(0,0,0)
{ id=0;
att=false;
}
void Log::login(int i, int h, int m, int s)
{
id = i;
in.set(h,m,s);
att = true;
}
void Log::logout(int h, int m, int s)
{
out.set(h,m,s);
att = false;
}
void Log::print()
{
cout<<setw(10)<<id;
in.print();
out.print();
cout<<endl;
}
The basic for declaring any constant variable from primitive types are:
const type x = initialization;
- Include the keyword: const before the type.
- Declare the wanted variable: int x;
- Must initialize the variable or it will be a syntax error.
x.set(1,1,1);
y.set(2,2,2); //Error set() isn’t const func.
x.print();
y.print();
}
Time::Time(int a, int b, int c) : hour(a),min(b),sec(c){}
//We have to include the keyword const in both prototype and
//definition header.
void Time::print() const
{
cout<<setw(10)<<hour<<’:’<<setw(2)<<min<<’:’
<<setw(2) <<sec;
}
void Time::set(int a, int b, int c)
{
hour = a; min = b; sec = c;
}
Note:
We MUST initialize the constant data members with intializer lists in
constructor, so:
- If we don’t have a constructor when using constant data members, it’ll be
a syntax error.
- If we don’t’ use the initializer lists when using constant data members,
it’ll be a syntax error.
void main()
{
Person x(“Sami”,’m’);
x.print();
Person y(“Ola”, ‘f’);
y.print();
}
Person :: Person(char a[], char g): gender(g)
{
name = new char[strlen(a)];
strcpy(name, a);
}
void Person :: print()
{
cout<<”Hi my name is ”<<name;
if(toupper(gender)==’F’)
cout<<”. And I’m a girl.\n”;
else
cout<<”. And I’m a boy.\n”;
}
Person :: ~Person ()
{
delete name;
}
But sometimes we need to have a global data member for all objects such
as their count. Here when we need to use the static data members.
Object X Object Y
Object X Object Y
cout<<mem;
cout<<x.mem;
cout<<y.mem;
cout<<className::mem;
void main()
{
//We can use the static members through the class name
//even before we declaring any objects.
cout<<”No. of objects: ”<<Person::count;
Person x(“Ali”); //Person::count=1
{
Person y(“Sami”); //Person::count=2
cout<<”No. of objects: ”<<Person::count;
} //Person::count=1
void main()
{
//We can use the static members through the class name
//even before we declaring any objects.
cout<<”No. of objects: ”<<Person::getCount();
Person x(“Ali”); //Person::count=1
{
Person y(“Sami”); //Person::count=2
cout<<”No. of objects: ”<<Person::getCount();
} //Person::count=1
a. Assignment
We can assign one object to another.
Because x, y and z are user-defined type. And the operator + can’t decide
how to work with them. But it will be allowed if we tell the compiler how the
operator + will word with objects of class Time. This is called operator
overloading.
So the prototype inside class definition for this operator will be:
Time operator +(Time a);
But if we want to make the operation of increment valid. This operation will
increase all members of Time by one, so it will have no return but just updating
the members:
x++; //It’s same to: x.operator++();
So the prototype inside class definition for this operator will be:
void operator ++();
Note:
- Here are some of the common operators that can be overloaded:
o Arithmetic: + – * / % ++ – –
o Assignments: += –= *= /= %= =
o Relational: == > < >= <= !=
o Boolean: ! || &&
- We can have more than one version of the overloaded operator since the type
of the second operand is differ.
void main()
{
Time x(12,0,0),y;
y = x + 10;
}
//See member functions definition in Example 2.15
//Here is the second version of overloaded operator +
Time Time::operator +(int a)
{
//Compute the new hours, minutes and seconds.
int h = hour+ a;
int m = min + a;
int s = sec + a;
a. Declaration Syntax:
Class_Name objName[row_number];
b. Initialization Syntax:
Class_name objName[row_number]={ Class_name(mem1, mem2),
Class_name(mem1,mem2),...};
void main()
{
//Declare an array and initialize part of it.
Person family[4]={Person(“Sami”,7),Person(“Ali”,8)};