המצגת נטענת. אנא המתן

המצגת נטענת. אנא המתן

עקרונות תכנות מונחה עצמים תרגול 8: OOP in C++

מצגות קשורות


מצגת בנושא: "עקרונות תכנות מונחה עצמים תרגול 8: OOP in C++"— תמליל מצגת:

1 עקרונות תכנות מונחה עצמים תרגול 8: OOP in C++

2 Outline העתקות איפה נשמרים המשתנים? Slicing
דריסה לעומת הסתרה (Overriding vs Shadowing) הורשה מרובה (Multiple Inheritance)

3 Copies and Clones When a language use pointer semantics for assignment, they almost always provide a means to create copy or clone from a value But even in this simple task there are subtle issues that can trap the unwary In particular, what actions should be taken when creating a copy of a value that itself points to other objects?

4 Copies and Clones There are two possible interpretations:
Shallow copy: Share instance variables with the original. The original and the copy reference the exact same value. Deep copy: Create new copies of the instance values. Recursively!

5 Copies and Clones Shallow Deep y x y x a b c a b c a' b' c'

6 Cloning in Java class PlayingCard implements Clonable { public … public Object clone() throws CloneNotSupportedException { Object newCard = super.clone(); return newCard; } The default behavior creates a shallow copy. If deep copy, or any other domain-specific behavior, is desired, the programmer can add code after invoking parent method

7 Return Type of clone is Object
One disadvantage with the design of the clone() method is that the return type of clone() is Object, and needs to be explicitly cast back into the appropriate type. However, overriding clone() to return the appropriate type is preferable and eliminates the need for casting in the client. Another disadvantage is that one often cannot access the clone() method on an abstract type. Most interfaces and abstract classes in Java do not specify a public clone() method. As a result, often the only way to use the clone() method is if you know the actual class of an object; which is contrary to the abstraction principle For example, if one has a List reference in Java, one cannot invoke clone() on that reference because List specifies no public clone() method.

8 Outline העתקות איפה נשמרים המשתנים? Slicing
דריסה לעומת הסתרה (Overriding vs Shadowing) הורשה מרובה (Multiple Inheritance)

9 Memory segment לכל תוכנית שרצה במחשב (בין אם נכתבה בג'אווה, ב++C, או בכל שפה אחרת) מוקצה מרחב זכרון עבור קוד התוכנית והמידע שלה. עבור משתני התכנית מוקצים שני מקטעים עיקריים – Stack & Heap כל אחד משני המקטעים שומר את המשתנים בדרך שונה ובעל ייעוד משלו

10 The Stack המחסנית משמשת לאחסון משתנים מקומיים ופרמטרים של פונקציה.
לכל פונקציה נפתח פריים משלה במחסנית, בו נשמרים המשתנים המקומיים שלה לכל משתנה יש כתובת והמשתנים נשמרים אחד לאחר השני לפי סדר הצהרתם בקוד בחזרה מהפונקציה, הפריים שלה במחסנית נסגר (וכל המידע המקומי נעלם) וחוזרים לפריים של הפונקציה שקראה לה (שנמצא מתחת במחסנית) main() f() כתובות קטנות

11 The Heap משמש לאחסון משתנים גם מעבר ל-scope של פונקציה בודדת
משמש להקצאה דינאמית של משתנים (לדוגמא, new בג'אווה) לכל משתנה יש את הכתובת שלו בניגוד למחסנית, בheap המשתנים לא מסודרים בהכרח ברצף, על פי סדר הקצאתם x y z

12 Where do the objects live?
בג'אווה כל המשתנים הפרימיטבים (int,double,char..) מוקצים על המחסנית, וכל האובייקטים מוקצים על הheap (כאשר במחסנית נשמר 'מצביע' למשתנים בheap) ה'מצביע' הוא למעשה הכתובת של המשתנה (המיקום שלו) ב-heap. ב++C, המתכנת יכול להקצות בשני האיזורים גם משתנים פרימטיבים וגם אובייקטים. x y כתובת x כתובת y

13 Where do the objects live?
Java public class Point{ protected int _x; protected int _y; public Point( int x, int y){ this._x = x; this._y = y; } public class Point3D extends Point{ private int _z; public Point3D( int x, int y, int z){ super(x,y); this_z = z; }

14 Where do the objects live?
class Point{ protected: int _x; int _y; public: Point( int x, int y): _x(x), _y(Y){ } }; class Point3D : public Point{ private: int _z; public: Point3D( int x, int y, int z): Point(x,y){ this->_z = z; } }; Initialization list רק בעזרתה ניתן לקרוא לבנאי האב

15 Variables in Java JAVA: public static void main(String[] args){
int x = 5; double y; char c = ‘A’; Point p1= new Point(1,1); Point3D p2= new Point3D(2,2,2); Point p3= new Point3D(1,2,3); }

16 Java variables 1 2 0x1000 p3 0x3000 3 p2 0x2000 0x3000 2 0x1000 p1 2
public static void main(String[] args){ int x = 5; double y; char c = ‘A’; Point p1= new Point(1,1); Point3D p2= new Point3D(2,2,2); Point p3= new Point3D(1,2,3); } Java variables 0x1000 1 2 p3 0x3000 3 p2 0x2000 0x3000 2 0x1000 p1 2 ‘A’ c 2 1 0x2000 y 1 5 0x1000 x

17 Variables in C++ C++: void main(){ int x = 5; double y; char c(‘A’);
Point *p1 = new Point(1,1); Point3D p2 (2,2,2); Point *p3 = new Point3D(1,2,3); } הגדרת משתנים ב-heap (ע"י יצירת מצביע עם new) הגדרת משתנה ב-stack (ע"י הצהרתו)

18 C++ variables p3 0x3000 3 2 2 p2 2 1 2 0x3000 0x1000 p1 ‘A’ c 1 y ? 1
void main(){ int x = 5; double y; char c(‘A’); Point *p1 = new Point(1,1); Point3D p2 (2,2,2); Point *p3 = new Point3D(1,2,3); } C++ variables p3 0x3000 3 2 2 p2 2 1 2 0x3000 0x1000 p1 ‘A’ c 1 y ? 1 5 0x1000 x

19 Memory management משתנים המוקצים על המחסנית, נמחקים ממנה ביציאה מהפונקציה בהם הוקצו (כי ה-frame של הפונקציה נמחק) משתנים המוקצים על הHeap יש למחוק במפורש. בג'אווה זה מתבצע על ידי ה Garbage Collector ב++C זה באחריות המתכנת

20 Memory management void main(){ Point *p1 = new Point(1,1);
Point3D p2 (2,2,2); Point *p3 = new Point3D(1,2,3); } 1,1 1,2,3 כתובת p1 p2 (2,2,2) כתובת p3 1,2,3 1,1

21 Memory management void main(){ Point *p1 = new Point(1,1);
Point3D p2 (2,2,2); Point *p3 = new Point3D(1,2,3); delete p1; delete p3; } 1,1 1,2,3 כתובת p1 p2 (2,2,2) כתובת p3 כתובת p1 p2 (2,2,2) כתובת p3 1,2,3

22 Memory management void main(){ Point *p1 = new Point(1,1);
Point3D p2 (2,2,2); Point *p3 = new Point3D(1,2,3); delete p1; delete p3; } 1,1 1,2,3 כתובת p1 p2 (2,2,2) כתובת p3 כתובת p1 p2 (2,2,2) כתובת p3

23 Outline העתקות איפה נשמרים המשתנים? Slicing
דריסה לעומת הסתרה (Overriding vs Shadowing) הורשה מרובה (Multiple Inheritance)

24 Slicing בשתי השפות, אפשר לבצע את הפעולות הבאות:
Point3D* p3d = new Point3D(1,2,3); Point* p = p3d ; זה מתאפשר כיוון שלא משנה אם האובייקט בheap הוא Point או Point3D, מה שנמצא על המחסנית זה רק הכתובת שלו (המצביע), וכיוון שכל הכתובות באותו גודל, אין בעיה שבp תהיה כתובת של Point3D. 1,2,3 p p3d

25 Slicing אבל מה יקרה בקטע הבא (שאפשרי רק ב++C): Point3D p3d(1,2,3);
Point p = p3d;

26 Slicing Point3D p3d(1,2,3); Point p = p3d; _y 2 p _x 1 _z 3 _y 2 p3d 1

27 Accessing object members
void main(){ Point *p1 = new Point(1,1); Point p2 (2,2); p1->x; p2.x; (*p1).x; } שני מקרים לשימוש ב-(*): הגדרת מצביע למשתנה על ה-heap Dereferencing (גישה למשתנה בכתובת מסוימת)

28 Outline העתקות איפה נשמרים המשתנים? Slicing
דריסה לעומת הסתרה (Overriding vs Shadowing) הורשה מרובה (Multiple Inheritance)

29 Inheritance in C++ ב++C לא קיים עץ ירושה יחיד (אין אובייקט Object שכולם יורשים ממנו), אלא מספר עצי ירושה. אפשר לרשת יותר ממחלקה אחת ב ++C אין ממשקים (interfaces) יש מחלקות אבסטרקטיות, אבל לא קיימת המילה השמורה abstract מחלקה נחשבת 'אבסטרקטית' אם קיימת בה לפחות פונקציה אבסטרקטית אחת כדי שיהיה ניתן לדרוס פונקציה יש לציין זאת במפורש (על ידי המילה השמורה virtual) כדי לציין שפונקציה היא אבסטרקטית יש לציין תחילה שהיא וירטואלית, ובנוסף להוסיף את האופרטור 0= בסוף החתימה שלה

30 Virtual method /* Point.h */ /* Point.cpp*/
class Point{ protected: int _x; int _y; public: Point( int x, int y): _x(x), _y(Y){ } virtual void print(); void moveToOrigin(); }; #include “Point.h” #include <iostream> Using namespace std; void Point:: print(){ cout << this->_x<<“ , “<< this->_y<<endl; } void Point::moveToOrigin(){ this->_x = 0 ; this->_y = 0 ;

31 Virtual method /* Point3D.h */ /* Point3D.cpp*/
class Point3D: public Point{ private: int _z; public: Point3D( int x, int y,int z); virtual void print(); void moveToOrigin(); }; Point3D:: Point3d(int x, int y, int z): Point(x,y){ this->_z = z; } void Point3D:: print(){ cout << this->_x<<“ , “<< this->_y; cout <<“ , “<< this->_z <<endl; void Point3D::moveToOrigin(){ this->_x = 0 ; this->_y = 0 ; this->_z = 0;

32 Late/Early Binding Output: 0 , 0 , 3 0 , 0 , 0
void main(){ Point *p2 = new Point3D(1,2,3); Point3D *p3 = new Point3D(4,5,6); p2->moveToOrigin(); P3->moveToOrigin(); p2->print(); p3->print(); delete p2; delete p3; } // call to Point:: moveToOrigin() // call to Point3D :: moveToOrigin() // call to Point3D :: print() Output: 0 , 0 , 3 0 , 0 , 0 // call to Point3D :: print()

33 Abstract class class Animal { protected: std::string name; int age; public: void printName(); virtual std::string say() =0; };

34 Outline העתקות איפה נשמרים המשתנים? Slicing
דריסה לעומת הסתרה (Overriding vs Shadowing) הורשה מרובה (Multiple Inheritance)

35 Multiple inheritance #include “ninja.h” #include “turtle.h” class NinjaTurtle: public Ninja, public Turtle{ … }; Since there are no interfaces in C++, multiple inheritance is important and useful for big systems, especially when using design patterns

36 Multiple inheritance- Pitfalls
Ambiguities: class A { virtual void f(); } ; class B { virtual void f(); } ; class C : public A, public B {}; Solution: Each base class can be uniquely identified by using the scope resolution operator :: . C *c = new C(); c->f(); //Ambiguous! Compilation error c->A::f(); c->B::f();

37 Multiple inheritance- Pitfalls
The Diamond Problem: Creature Ninja Turtle NinjaTurtle בירושה ב-C++ המימוש של המחלקות יועתקו אחד לאחר השני. במקרה זה, המימוש של Creature יועתק פעמיים ויהיה חוסר בהירות לאיזה אחד מתכוונים אם ניגש לפונקציה של Creature.

38 Multiple inheritance- Pitfalls
class Creature { void f(){ std::cout << "hello"; } }; class Ninja : public Creature {} ; class Turtle: public Creature {} ; class NinjaTurtle : public Ninja, public Turtle { }; int main() { NinjaTurtle rafael; rafael.f(); } In function 'int main()': 18:10: error: request for member 'f' is ambiguous 5:31: note: candidates are: void Creature::f() 5:31: note: void Creature::f()

39 Multiple inheritance- Pitfalls
Ninja Turtle NinjaTurtle Creature Ninja Turtle NinjaTurtle Creature Creature Solution: virtual inheritance class Turtle : virtual public Creature class Ninja: virtual public Creature

40 Summary Copy & Clone Where do the objects live Slicing
Deep vs Shallow copy Where do the objects live Java – primitive on the stack, objects on the heap C++ - Wherever you decide Slicing When polymorphism meets the stack

41 Summary Inheritance Multiple inheritance C++ has no interfaces
No one single inheritance tree Can override only virtual function (or you will get shadowing) Multiple inheritance Doesn’t exist in Java, very useful in C++ Programmer should avoid ambiguities and diamond inheritance


הורד את "ppt "עקרונות תכנות מונחה עצמים תרגול 8: OOP in C++

מצגות קשורות


מודעות Google