LECTURE 4. Composition Definition: A data member of a class is an object of some other class...

Preview:

Citation preview

LECTURE 4

CompositionDefinition: A data member of a class is an

object of some other classExample: an AlarmClock object needs to

know when it is supposed to sound its alarm, so why not include a Time object as a member of the AlarmClock class?

Referred to as has-a relationshipreusability

//Date.h#ifndef DATE_H #define DATE_H class Date{

public:Date(int=1, int=1, int=1900);void print() const;~Date();

private:int month; //1-12int day; //1-31 based on monthint year;//utility function to check if day is proper for

month and yearint checkDay(int) const;

};

//Date.cpp#include "date.h"#include <iostream>using namespace std;Date:: Date(int mn, int dy, int yr) {

if (mn>0 && mn<=12)month=mn;

else {month=1;cout<<"invalid month; set to 1\n";}

year =yr;day =checkDay(dy);cout<<"Date object constructor for date " ;print();cout<<endl;

}void Date::print() const{ cout<<month<<'/'<<day<<'/'<<year; }

Date::~Date(){

cout<<"Date object destructor for date "; print();cout<<endl;

} int Date::checkDay(int testDay) const{

const int daysPerMonth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};if (testDay >0 && testDay<=daysPerMonth[month])

return testDay;if (month==2 && testDay==29 && (year%400==0|| (year%4==0 && year%100!=0)))

return testDay;cout<<"invalid Day; set to 1\n";return 1;

}

//Employee.h#ifndef EMPLOYEE_H#define EMPLOYEE_H#include "d:\projects\composition\Date.h"#include <iostream>using namespace std; class Employee{

char firstName[25];char lastName[25];const Date birthDate; //composition: member objectconst Date hireDate; //composition: member objectpublic:

Employee(const char * const, const char * const, const Date &, const Date &);

void print() const;~Employee();

};#endif

//Employee.cpp#include "d:\projects\composition\Date.h"#include "d:\projects\composition\Employee.h"

//ctor uses member initializer list to pass initializer//values to ctors of member objects//Note: this invokes the default copy ctorEmployee::Employee(const char * const first, const char * const last,

const Date & dateOfBirth, const Date & dateOfHire) :birthDate(dateOfBirth), hireDate(dateOfHire)

{int length=(int)strlen(first);length=(length<25 ? length:24);strncpy(firstName, first, length);firstName[length]=‘\0';

length=(int)strlen(last);length=(length<25 ? length:24);strncpy(lastName, last, length);lastName[length]=‘\0';

cout<<"Employee object ctor: "<<firstName<<' ' <<lastName;}

void Employee::print() const{

cout<<lastName<<", "<<firstName<<" Hired: ";hireDate.print();cout<<" Birthday: ";birthDate.print();cout<<endl;

}

Employee::~Employee(){

cout<<" Employee object destructor: " <<lastName<<", "

<<firstName<<endl;}

//test.cpp#include "Employee.h" void main(){

Date birth(7, 24, 1949);Date hire(3, 12, 1988);Employee manager("Bob", "Blue", birth, hire);cout<<endl;manager.print();

}

Order of Constructor and Destructor for CompositionMember objects are constructed in the order

in which they are declared in the class definition (not in the order they are listed in the constructor’s member initializer list) and before their enclosing class objects are constructed

Member objects are constructed from the inside out and destroyed in the reverse order

Compilation error occurs if a member object is not initialized with a member initializer and the member object’s class doest not provide a default constructor

Initialize member objects explicitly through member intializers. This eliminates the overhead of doubly initializing

#include <iostream>using namespace std;class Point{

int x,y;public:

Point(): x(0), y(0){cout<<"ctor for point: "<<x<<' '<<y<<endl;}void get() const{

cout<<x<<' '<<y<<endl;}void set(int a, int b){

x=a;y=b;

}~Point(){cout<<"dtor for point: "<<x<<' '<<y<<endl;}

};

class Circle{

Point center; //COMPOSITIONint radius;

public:Circle(): radius(0){cout<<"ctor for circle: ";center.get(); cout<<' '<<radius<<endl;}~Circle(){cout<<"dtor for circle: ";center.get(); cout<<' '<<radius<<endl;}

};

void main(){

Circle c;}

FriendshipFriends of a class are not members of the

class, yet can access the non-public members of the class

A class can have two types of friendsFriend functionsFriend classes

Friendship• Friendship is granted, not taken-i.e. for class B

to be a friend of class A, class A must explicitly declare that class B is its friend.

• Friendship is not symmetric. For example, if class A is a friend of class B, this does not necessarily mean that class B is also a friend of class A.

• Friendship is not transitive. For example if class A is a friend of class B and class B is a friend of class C, we cannot infer that class A is a friend of class C.

Friend Functions• To declare a function as friend of a class,

precede the function prototype in the class definition with keyword friend.

• Member access notions of private, public etc. are not relevant to friend declaration, so friend declarations can be placed anywhere in a class definition.

• As a good programming practice, place all friendship declarations first inside the class definition’s body and do not precede them with any access specifier

Friend Function Example class Count{

friend void setX(Count &, int);public:

Count(): x(0) {}void print() const {cout<<x<<endl;}

private:int x;

};

Friend Function Example void setX(Count & c, int val){

c.x=val;} void main(){

Count counter;counter.print();setX(counter, 8);counter.print();

}

Friend Class Example#include <iostream>using namespace std;class A{

friend class B;int x;

public:A(): x(0){}int get() const{ return x; }void set(int y){ x=y; }

};

Friend Class Exampleclass B

{int z;public:

void set(A & a){

a.x=20;}int get() const{

return z;}

};

Friend Class Examplevoid main(){

A a1;B b1;b1.set(a1);cout<<a1.get()<<endl;

}

static Data Members• Normally, each object maintains its own copy

of data members.• However, if some data item in a class is

declared static, only one such item is created for the entire class, no matter how many objects are there.

• A static data item is useful when all objects of the same class must share a common item of information.

static Data Members A static data member exists even if there are

no objects of the class instantiated. Static class member data is used to share

information among the objects of a class.

class foo{

private:static int count; //only one data item for all objects

//Note: declaration onlypublic:

foo() {count++; } //increments count when object created

int getcount() {return count; }}; int foo::count=0; void main(){

foo f1, f2, f3;cout<<f1.getcount()<<f2.getcount()<<f3.getcount(); //each object sees the same value

}

Recommended