Você está na página 1de 26

Programming 2

Object Oriented Programming


Daniel POP

Week 5
Programming II Object-Oriented Programming

Agenda
1. Modifiers: friend

2. Objects

Programming II

Object-Oriented Programming

Wrap-up last week

Self-reference

Modifiers:
static const mutable

Programming II

Object Oriented Programming

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)); }

Nota: Solution for m1() - declare it as global function, friend of X


Programming II
Object-Oriented Programming

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

Object Instantiation - Summary


#
1

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

Dynamic allocation (Free-store) Local static variable

4
5

Array of objects
Non-local object

When array is created


Once at the start of the program

When array is destroyed


Once at the termination of the program At the end of the full expression in which it occurs

Temporary object

When the expression is evaluated

Dynamic allocation in user-supplied memory


Union member Non-static member object

Using an overloaded version of operator new

Using delete operator

8 9

When the enclosing object is created

When the enclosing object is destroyed

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

Date d4; } // destroying objects d4, d2, d1 (in this order)

Objects are destroyed in reverse order of their creation.

Programming II

Object-Oriented Programming

Free store (Dynamic allocation)


int f(int a) { Date *d1 = new Date(03, 03, 2007); // creating the object if(a>0) { Date *d2 = new Date; cout << *d2; delete d2; } delete d1; }

Operator new allocates and initializes memory from free store


Syntax

Operator delete de-allocates and cleanup memory


DO NOT FORGET TO DESTROY ALL OBJECTS ALLOCATED USING NEW OPERATOR !
Programming II
Object-Oriented Programming

X* p = new X;

X* p = new X(init_value);

delete p;

Local static variable


int f(int a) { static Date d(03, 03, 2007); // static object } // d is not destroyed!

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);

Non-local = global, namespace or class static variables

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); }

Should be used with caution! Ask experienced colleagues first.

PersistentStorage* ps = new FileStorage(a.bin);

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

Non-static members (I)


class Student { Date dob; // non-static member String name; // non-static member public: Student(const char* n, const Date& d); }; Student::Student(const char* n, const Date& d) { dob = d; name = String(n); } void f() { Date d(7, 8, 1988); Student aStudent(Popescu, d); }

Steps to initialize aStudent object: (1) Memory allocation = sizeof(Date) + sizeof(String)


(2) Call default constructor for Date to initialize dob member. (3) Call default constructor for String to initialize name member. (4) Call the Student::Student(n,d) constructor. (5) Call assignment operator in line dob=d; (6) Call assignment operator in line name=n;

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

Non-static members (II)


class Student { Date dob; // non-static member String name; // non-static member public: Student(const char* n, const Date& d); };

Steps to initialize aStudent object: (1) Memory allocation = sizeof(Date) + sizeof(String)


(2) Call the copy constructor of Date to initialize dob in dob(d) (3) Call the custom constructor of String to initialize name in name(n) (4) Call Student::Student(n,d)

Student::Student(const char* n, const Date& d) : name(n), dob(d) { }


void f() { Date d(7, 8, 1988); Student aStudent(Popescu, d); }

The real initialization of dob/name objects is done in one step: calling the appropriate constructor.

Programming II

Object-Oriented Programming

Non-static members (III)


Order of initialization: 1. Initialize members in order of their declaration in class (the order in initialization list is irrelevant). 2. Call the constructor of the class. Order of destroy: 1. Call the destructor of the class. 2. Call the members destructor in reverse order of declaration. The following members can be initialized only in initialization list: References (X& member;) const (const int member;) Types without default constructor (X member;)
class Club { Club(); // private default constructor public: Club(const char* s); }; class X { // declaration + initialization static const int ci = 1; // error: not int! static const float cf = 9.0; const int i; Date& date; Club club; public: X(int ii, Date& dd, const char* clubName) : i(ii), date(dd), club(clubName) { i = ii; // error const member } }; const int X::ci; // definition 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

Object Oriented Programming

Você também pode gostar