OBJECTS AND CLASSES (CONTINUED)
A LECTURE FOR THE C++ COURSE
Each slide may have its own narration in an audio file. �For the explanation of any slide, click on the audio icon to start the narration.
The Professor‘s C++Course by Linda W. Friedman is licensed under a �Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
CONTINUING FROM PART 1
Previously we saw the definition and implementation of the Fraction class. We continue now with the Objects and Classes lecture.
OBJECTS AND CLASSES
2
CONSTRUCTORS
The assign function in the previous example is an awkward way to initialize objects.
A constructor is a member function that is invoked automatically when an object is declared. It has the same name as the class and carries no return type (not even void). The default constructor, e.g., Fraction(), does not take parameters. If the programmer does not supply it, the system will generate one (without default parameter values, of course).
OBJECTS AND CLASSES
3
CONSTRUCTORS
//fraction2.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction (int n, int d) {num = n; den = d;}
void print(){cout << num << '/' << den;}
private:
int num, den;
};
int main(){
Fraction x(-1,3), y(22,7);
cout << "x = "; x.print();
cout << " and y = "; y.print();
cout << endl;
return 0;
}
OBJECTS AND CLASSES
4
CONSTRUCTORS
Overloading the constructor function
//fraction3.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction() {num = 0; den = 1;} //default parameter values
Fraction(int n) {num = n; den = 1;} //only 1 default value
Fraction (int n, int d) {num = n; den = d;}
void print(){cout << num << '/' << den;}
private:
int num, den;
};
int main(){
Fraction x, y(4), z(22,7);
cout << "x = "; x.print();
cout << "\ny = "; y.print();
cout << "\nz = "; z.print();
cout << endl;
return 0;
}
OBJECTS AND CLASSES
5
Which constructor is called? That depends on the parameter list in the declaration of the object.
CONSTRUCTORS
Using constructor initialization lists. This program produces the same output as the last one.
//fraction4.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction() : num (0), den (1) {}
Fraction(int n) : num (n), den (1) {}
Fraction (int n, int d) : num (n), den (d) {}
void print(){cout << num << '/' << den;}
private:
int num, den;
};
int main(){
Fraction x, y(4), z(22,7);
cout << "x = "; x.print();
cout << "\ny = "; y.print();
cout << "\nz = "; z.print();
cout << endl;
return 0;
}
OBJECTS AND CLASSES
6
CONSTRUCTORS
Also this one. When actual parameters are not passed, the default values are used.
//fraction5.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction (int n=0, int d=1) : num (n), den (d) {}
void print(){cout << num << '/' << den;}
private:
int num, den;
};
int main(){
Fraction x, y(4), z(22,7);
cout << "x = "; x.print();
cout << "\ny = "; y.print();
cout << "\nz = "; z.print();
cout << endl;
return 0;
}
OBJECTS AND CLASSES
7
CONSTANT OBJECTS
Objects may be declared to be constant, eg.
const Fraction PI(22,7);
This will limit access to the object's member functions. For ex, the print function could not be called for PI.print(). To enable access of the objects member functions when the objects is declared a constant, we must declare the member functions const as well, e.g.,
void print() const {cout <<num << '/' << den << endl;}
OBJECTS AND CLASSES
8
ACCESS FUNCTIONS
It is common practice to include public member functions that provide a "read-out" of the values of an object's private data items. These access functions, also called get functions, will frequently be labeled const functions so that they cannot change the values of the object data, only report them.
OBJECTS AND CLASSES
9
ACCESS FUNCTIONS
//fraction6.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction (int n=0, int d=1) : num (n), den (d) {}
int getnumerator() const {return num;}
int getdenominator() const {return den;}
private:
int num, den;
};
int main(){
Fraction x(22,7);
cout << x.getnumerator() <<'/'
<< x.getdenominator() << endl;
return 0;
}
OBJECTS AND CLASSES
10
PRIVATE MEMBER FUNCTIONS
Sometimes we need private "utility" functions, used only by the object itself. No outsider needs access to them.
//fraction7.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction (int n=0, int d=1) : num (n), den (d) {reduce();}
void print(){cout << num << '/' << den;}
private:
int num, den;
int gcd (int j, int k) {if (k==0) return j; return gcd(k, j%k);}
void reduce () {int g = gcd(num, den); num /= g; den /= g;}
};
int main(){
Fraction x(100,360);
x.print();
return 0;
}
OBJECTS AND CLASSES
11
COPY CONSTRUCTOR
The copy constructor builds an object by copying the state of an existing object into a new object of the same class. There are two default constructors; if necessary they will be automatically provided by the system. These are, e.g.,
Fraction (); and
Fraction (const Fraction&);
It's better to include it ourselves. This gives us more control over the program.
OBJECTS AND CLASSES
12
COPY CONSTRUCTOR
//fraction8.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction (int n=0, int d=1) : num (n), den (d) {reduce();}
Fraction (const Fraction& r) : num(r.num), den(r.den){}
void print(){cout << num << '/' << den;}
private:
int num, den;
int gcd (int j, int k) {if (k==0) return j; return gcd(k, j%k);}
void reduce () {int g = gcd(num, den); num /= g; den /= g;}
};
int main(){
Fraction x(100,360);
Fraction y(x);
cout << "x= "; x.print();
cout << "\ny= "; y.print();
return 0;
}
OBJECTS AND CLASSES
13
DESTRUCTOR
Just like a constructor is called automatically when an object is declared/created, so a destructor is called automatically when an object comes to the end of its life. The destructor has the same name as the class, except that the name must begin with a tilde (~). It has no return type, not even void. If not defined explicitly, a default destructor will be created by the system. A class may have multiple constructors, but only one destructor. The destructor is not called explicitly.
OBJECTS AND CLASSES
14
DESTRUCTOR
//fraction9.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Fraction {
public:
Fraction (int n=0, int d=1) : num (n), den (d)
{reduce(); cout << "Object born";}
~Fraction() {cout << "\nObject dies";} //destructor
void print(){cout << num << '/' << den;}
private:
int num, den;
int gcd (int j, int k) {if (k==0) return j; return gcd(k, j%k);}
void reduce () {int g = gcd(num, den); num /= g; den /= g;}
};
int main(){
{ Fraction x(22,7);
cout << "\nx is alive and = "; x.print();
}
cout << "\nNow we are between blocks.\n";
{ Fraction y;
cout << "\ny is alive and = "; y.print();
}
return 0;
}
OBJECTS AND CLASSES
15
STATIC DATA MEMBERS
Static attributes are used when a single value for a data member applies to all objects of the class. The variable must be declared globally. These variables are automatically initialized to 0.
OBJECTS AND CLASSES
16
STATIC DATA MEMBERS
//fraction10.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Widget {
public:
Widget() {++count;}
~Widget() {--count;}
int numWidgets() {return count;} //access function
private:
static int count; //private and static
}; //accessible to all objects of the class
int Widget:: count = 0;
int main(){
Widget w, x;
cout << "There are " << w.numWidgets() << " widgets.\n";
{
Widget w,x,y,z;
cout << "There are " << w.numWidgets() << " widgets.\n";
}
cout << "There are " << w.numWidgets() << " widgets.\n";
Widget y;
cout << "There are " << w.numWidgets() << " widgets.\n";
return 0;
}
OBJECTS AND CLASSES
17
STATIC DATA MEMBERS
A function can also be static. Since a static function is not "owned" by any single object of the class, it can be called even before any objects are declared.
Improved program on the next slide.
OBJECTS AND CLASSES
18
STATIC DATA MEMBERS
//fraction11.cpp
//modified from Hubbard
#include <iostream>
using namespace std;
class Widget {
public:
Widget() {++count;}
~Widget() {--count;}
static int numWidgets() {return count;}
private:
static int count;
};
int Widget::count = 0;
int main(){
cout << "There are " << Widget::numWidgets () << " widgets.\n";
Widget w, x;
cout << "There are " << Widget::numWidgets () << " widgets.\n";
{
Widget w,x,y,z;
cout << "There are " << Widget::numWidgets () << " widgets.\n";
}
cout << "There are " << Widget::numWidgets () << " widgets.\n";
Widget y;
cout << "There are " << Widget::numWidgets () << " widgets.\n";
return 0;
}
OBJECTS AND CLASSES
19
REVIEW
OBJECTS AND CLASSES
20
What did we learn in this lecture? Plenty. Some terms to jog your memory: