object oriented programming elhanan borenstein [email protected] lecture #6

21
Object Oriented Programming Elhanan Borenstein [email protected] Lecture #6

Upload: clyde-weaver

Post on 26-Dec-2015

222 views

Category:

Documents


0 download

TRANSCRIPT

Object OrientedProgramming

Elhanan Borenstein

[email protected]

Lecture #6

Agenda Operator Overloading – Cont’

Inheritance – Part 1

Operators Overloading

Operators Overloading

Most operators cannot be automatically applied to objects though. (which can?)

However… we can define (overload) all available operators for classes too.

For example:

Operator Overloading Example

class CPoint {

int m_x, m_y; public:

CPoint(int ax, int ay):m_x(ax), m_y(ay){}CPoint operator+(const CPoint& p) const;

};

CPoint CPoint::operator+(const CPoint& p) const{

return CPoint(m_x + p.m_x, m_y + p.m_y);}

Operators Overloading

An operator should be overloaded only when its behavior is obvious. Otherwise, a function should be used.

An overloaded operator should work in an analogous manner to the fundamental types. It should also have the same behavior.

Efficiency is essential: Object parameters will pass ByRef Object parameters that should not be changed will be defined

as const An operator that returns a local object should return it ByVal

(preferably as a temp object within the return command) Operators that returns the activating object or an object that

was passed as a parameter should return it ByRef

Guidelines

Operators Overloading

Operators can be overloaded in two manners:

1) As a method (member function) – An activating object is mandatory (parameters are optional)

The assignment operator can be overloaded only as a method.

2) As a global function - Only parameters We will usually prefer to define the function as a friend function

Access to private data members Declaration within the class

In some cases, we must use global function rather than a method.

When using a global function, there is always an additional parameter. (the first parameter will substitute for the activating object)

Methods (Member Functions) vs. Friend Functions

Operators Overloading

The CArray class.

Example

Operators OverloadingThe ->, * Operators for Smart Pointer

class Data {

… public:

void Init(){…}};

class DataPtr{

Data* pd; public:

DataPtr(Data* p) : pd(p){ }Data* operator->() { return pd; }Data& operator*() { return *pd; }operator Data*() { return pd; }

};

void func1(const Data* p);void func2(const Data& d);

void main() {

Data d;DataPtr p = &d;

p->Init();func1(p);func2(*p);

}

Inheritance

Inheritance

Inheritance is one of the fundamental features of OOP. In many cases we wish to extend an existing class (without

replicating its source code), but … We may be unable (or unwilling) to change the original base

class: The existing base class is still in use in its original form. The original base class works fine (and we do not want to introduce new

bugs) There is no access to the original class source code (only the .obj and

header files exists) There are similar entities (with a common base) we wish to represent. (

polymorphism)

The resulting code is easier to read and maintain and does not include redundant code

Motivation

InheritanceExample

class Base1 {

int var1; public:

Base1() {…} // constructorvoid OldFunc() {…}void Init() {…}

};

class Derived1 : [public|protected|private] Base1{

int var2; public:

Derived1() {…} // constructorvoid Init() {…} // overridevoid Do(){…}

};

Inheritance

When inheriting a class, we inherit all its members and they will be included in the derived class:

Somewhat similar to object data members (embedded):

To differentiate, we can check the logics behind the implemented entities: Inheritance: The derived class is a type of the base class.

Inner class: The inner class is a part of the external class.

The Logic behind Inheritance

Base (father)

AdditionsDerived (son) (SIZE?)

Additions

embeddingclass

inner object

InheritanceUnderstanding Inheritance - Example

class GraphicItem {

int color; public:

GraphicItem() {…} // constructorvoid Draw() {…}void ChangeColor(int n_clr) {…}

};

class CPoint : public GraphicItem{

int m_x, m_y; public:

CPoint() {…} // constructorvoid Draw() {…} // overridevoid Align(){…}

};

GraphicItem G, *pG;CPoint P, *pP;…

G = P;

P = G;

pG = pP;

pP = pG;

Inheritance

Inheritance is a logical specification (narrowing) of an entity, but… usually a physical extension of it.

The derived class can override methods that were inherited from the base class.

In this lecture, we will focus on public inheritance. When inheriting a class, we inherit all its members -

partial inheritance is not possible. …However, we may not be able to access all of them.

Inheritance Concepts

Inheritance

All the data members of the base class also exists in the derived class. But…: There are cases where we cannot access these members. They will still be included in the derived object size.

When won’t we be able to access the base class members: Hiding – The derived class has defined a data member with the same

name. We can still access the hidden data member using its full name (base_class::member)

Private Permissions – Any private member of the base class cannot be accessed in the derived class. Note: the private data member is still included in the derived class (and can be accessed using a public method of the base class).

A good design, will include in the base class only data members that are common (and can be accessed) by all derived classes.

Accessing the Base Class Data Members

Inheritance

The derived class also inherit all the base class methods. The derived class can override inherited methods. When activating a method of an object from the derived class:

> If the inherited method was not overridden the base method (from the base class) will be activated.

> If the method was overridden in the derived class, the method of the derived class will be activated.

We can still activate the base method using its full name. It is very common to include a call to the base method from the derived method.

C’tor, D’tor and C.C. are the only methods that have a different behavior when inherited.

Using the Base Class Member Functions

Inheritance

C’tor and D’tor are not inherited (WHY?). Constructing an object of the derived class, always activates

first the C’tor of the base class (to create the base part of the object).

The order is thus as follows: The C’tor of the base class is activated. The additional data members of the derived class are created. If some of the data members are objects the C’tor of each such object

is activated. The C’tor of the derived class is activated

The order of the D’tor’s activation is of course reversed. What if the C’tor of the base class has parameters?

C’tor and D’tor in Inherited Classes

Inheritance

If the C’tor of the base class has parameters we must use the initialization line (in an analogous manner to object data members):

C’tor and D’tor in Inherited Classes – Cont’

class CRect {

CPoint pnt1, pnt2; public:

CRect(int x1, int y1, …) : pnt1(x1,y1), pnt2(0,0) {…} // c’tor};

class CGraphicRect : public GraphicItem{

… public:

CGraphicRect(int color) : GraphicItem(color) {…} // c’tor};

EmbeddedObjects

Inheritance

Inheritance

The assignment operator in not inherited. If the derived class did not implement the assignment

operator, when copying, the base class assignment operator will not be activated but rather the default assignment operator of the derived class.

But… as part of the default assignment operator action, (when the base class members should be copied), the base class assignment operator will be activated.

Example: Stack

Assignment Operator (=) in Inherited Classes

Inheritance

Rule of thumb: A derived class should implement an assignment operator only if it performs dynamic allocation. The same is true for the copy constructor and the destructor.

Remember the triplet: Copy Constructor Destructor Assignment Operator

Example: AB.cpp

Assignment Operator (=) in Inherited Classes

Questions?