Professional Documents
Culture Documents
Object Oriented Programming
Object Oriented Programming
Week 5
Programming II Object-Oriented Programming
Agenda
1. Modifiers: friend
2. Objects
Programming II
Object-Oriented Programming
Self-reference
Modifiers:
static const mutable
Programming II
Friends (I)
class Matrix { /* declarations */ }; class Vector { /* declarations */ }; Define a function that: Vector x Matrix Vector
Rationale: functions need access to private members of one class Solution: make those functions members of the class What happens if one function need to have access to private members of 2 or more classes? It can be member of only one class :-(
Friends help us to do this :-)
Programming II
Object-Oriented Programming
Friends (II)
DEFINITION [Friend functions] Friend functions are functions that are not members of one class, yet they have access to private members (data + functions) declared in that class. DEFINITION [Friend class] If class X is friend class of class Y, then all member functions of class X are friend functions (i.e. have access to private members) of class Y. Its not relevant the access control modifier (private, public, protected) used to declare a friend function/class, because friend functions are not member of the class for which they are friend. Friends can be either functions that are member of another class, or global functions.
Syntax friend ftype fname([arg_list]);
friend class X;
Programming II
Object-Oriented Programming
Friends (III)
class Matrix; // Forward declaration class Vector { float v[4]; public: Vector(float v0=0, float v1=0, float v2=0, float v3=0); friend Vector multiply(const Vector&, const Matrix&); }; class Matrix { Vector rows[4]; friend Vector multiply(const Vector&, const Matrix&); };
Vector multiply(const Vector& v, const Matrix& m) { v[0] = 0; // OK or ERROR? rows[0][0] = 0; // OK or ERROR } void main() { Matrix m; Vector v(1.0, 2.5, 5.0, 6.0); Vector w = multiply(v, m); // w = v x m }
Programming II
Object-Oriented Programming
Friends (IV)
One of the key principle OO is data hiding (encapsulation), but sometimes is to restrictive and needs to be broken =====> Not recommendable to use friends; use only if its impossible to solve the problem otherwise.
Programming II
Object-Oriented Programming
Friends (V)
More examples: see operator overloading Finding friends: declared before or identifiable by argument type Friendship is NOT reflexive nor transitive Friendship is not inherited
Action Non-static member function x x x Static member function x x Friend function
Has access to private members Is declared in the class scope (transparently) Receives this pointer
Programming II
Object-Oriented Programming
Member or Friend?
Some operations can be performed only by members: constructor, destructor, virtual functions A function that has to access the members of a class should be a member unless theres a specific reason for it not to be a member. Prefer member functions over friends because of clearer syntax. Member functions must be invoked for objects of their class only; no user defined conversions are applied. For example, if transpose function transposes its calling object instead of creating a new transposed matrix then it should be a member of class. Example: (see also operator overloading for more examples)
class X { public: X(int); void m1(); friend int f1(X&); friend int f2(const X&); friend int f3(X); }; void f() { 7.m1(); // err: X(7).m1() is not tried! f1(7); // err: f1(X(7)); is not tried because no implicit conversion is used for non-const references f2(7); // ok: f3(X(7)); f3(7); // ok: f3(X(7)); }
Exercise
GAME OF SOCCER: Add details to classes that model Soccer game.
Programming II
Object-Oriented Programming
Objects
DEFINITION [Object] An object is an instance of a class. It can be uniquely identified by its name, it defines a state which is represented by the values of its attributes at a particular time and it exposes a behaviour defined by the set of functions (methods) that can be applied to it. The simplest way to create an object in C++ is by variable declaration. If a variable is an instance of a class/struct then it is also called object.
int main(int, char*[]) { Date day1; // <- 1st object Date day2(25, 12); // <- 2nd object Date *today = new Date(15, 03, 2004); // <- 3rd object cout << Today is " << today->getDay() << / << today->getMonth() << / << today->getYear(); delete today; return 0; }
Programming II
Object-Oriented Programming
Type
Local variable
When is constructed
Each time its declaration is encountered in the execution of the program Using new operator First time its declaration is encountered in the execution of the program
When is destroyed
Each time the program exits the block in which it occurs Using delete operator Termination of the program
2 3
4
5
Array of objects
Non-local object
Temporary object
8 9
Programming II
Object-Oriented Programming
Local variable
int f(int a) { Date d1, d2(03, 03, 2007); // creating the objects if(a>0) { Date d3=d1; // creating object using copy-constructor } // d3 is destroyed
Programming II
Object-Oriented Programming
X* p = new X;
X* p = new X(init_value);
delete p;
The destructors for static objects are called in reverse order when the program terminates.
Programming II
Object-Oriented Programming
Array of objects
int f(int a) { Date week[7]; // an array of 7 Date objects Date *year = new Date[365]; delete [] year; }
Syntax X array[size]; X* p = new X[size];
delete [] p;
A default constructor for Date type is mandatory. There is no way to specify explicit arguments for a constructor in an array declaration. The destructor for each element of an array is invoked when the array is destroyed. Dont forget the squared brackets in delete to free all the elements (delete [] array)
Programming II
Object-Oriented Programming
Non-local variable
Date gdate1; int f(int a) { cout << gdate1; } Date gdate2(1,1,1970); class X { static Date referenceDate; };
Date X::referenceDate(1,1,1970);
Any global object (declared outside any function) is constructed before function main is invoked, in the order of their definitions.
The destructors for static objects are called in reverse order when the program terminates. No implementation-independent guarantees are made about the order of construction/destruction of non-local objects in different compilation units (files).
Programming II
Object-Oriented Programming
Temporary object
class String { char *s; public: char* c_str(); // TODO: add the rest // of required members }; void f(String& s1, String& s2) { // ... cout << s1 + s2; // ... } String temp = s1 + s2; cout << temp; destroy temp;
- Temporary objects are results of expression evaluation (e.g. arithmetic operations) - A temporary object can be used as initializer for a const reference or named object: const string& s = s1+s2; string s = s1+s2; - A temporary object can also be created by explicitly invoke the constructor handleComplex(complex(1,2)); - Problems may arise. See below.
void f(String& s1, String& s2) { // c_str() returns a C-style, zero-terminated array of chars const char* pch = (s1+s2).c_str(); cout << pch; // pch points to an invalid memory address that was destroyed together with // the temporary obj. s1+s2 } Programming II
Object-Oriented Programming
User-supplied memory
void* operator new(size_t, void* p) { return p; // memory area } // Explicit placement operator
void* buf = reinterpret_cast<void*>(0xF00F); // nasty, nasty! // placement syntax X* p2 = new (buf) X; // invokes operator new(sizeof(X), buf);
class PersistentStorage { virtual void* alloc(size_t) = 0; virtual void free(void*)=0; }; void* operator new(size_t s, PersistentStorage* p) { return p->alloc(s); } void destroy(X* p, PersistentStorage* storage) { p->~X(); // explicit call of destructor storage->free(p); // release the memory }
void f() { X* p1 = new (ps) X; X* p2 = new (ps) X[10]; X* p3 = new (ps) X(3); destroy(p1, ps); destroy(p1, ps); destroy(p1, ps); }
Programming II
Object-Oriented Programming
Union members
class X { }; union AUnion { int x; char name[12]; X obj; // OK: No constructors or destructor defined for type X Date date; // ERROR: Date has constructors and destructor void f(); };
A union can have member functions. A union cant have static members. A union cant have members with custom constructors or destructor.
Programming II
Object-Oriented Programming
The real initialization of dob and name objects is done in 2 steps: a default constructor + an assignment operator (steps 2+5 and 3+6).
Programming II
Object-Oriented Programming
The real initialization of dob/name objects is done in one step: calling the appropriate constructor.
Programming II
Object-Oriented Programming
static const integer members (and only these) can be initialized at declaration.
Exercise
GAME OF SOCCER: Create the two teams, the field and the referees.
Programming II
Object-Oriented Programming
Further Reading
1. [Stroustrup, 1997] Bjarne Stroustrup The C++ Programming Language 3rd Edition, Addison Wesley, 1997 [Chapter 10, 11.5]
Programming II