slicing
play

Slicing Imagine we have a hierarchy of shape shapes with the - PowerPoint PPT Presentation

Slicing Imagine we have a hierarchy of shape shapes with the following inherits members get_name(): circle triangle the name assigned to the shape get_area(): the area occupied by the shape We also provide swap(&,


  1. Slicing  Imagine we have a hierarchy of shape shapes with the following inherits members • get_name(): … circle triangle the name assigned to the shape • get_area(): the area occupied by the shape  We also provide swap(&, &) for exchanging two shapes of the same type  Let us implement bubble sort Th. Gschwind. Advanced Software Engineering with C++ Templates. 356

  2. Bubble Sort for a vector<shape*> void sort(vector<shape*> &v) { if (v.size() < 2) return ; bool rerun; do { rerun = false; for (size_t i = 0; i < v.size()-1; ++i) { if (v[i]->get_area() > v[i+1]->get_area()) { swap(*v[i], *v[i+1]); rerun = true; } } } while (rerun); }  When we invoke swap, we exchange the contents of the shapes at v[i] and v[i+1]  To do this, swap(shape&, shape&) is invoked Th. Gschwind. Advanced Software Engineering with C++ Templates. 357

  3. Bubble Sort for a vector<shape*> (cont’d) void swap(shape &s1, shape &s2) { shape t = s1; s1 = s2; s2 = t; }  Since the swap function only has space for a shape inside t, only the shape part of s1 is assigned to t  Only the shape part of s2 can be assigned to s1 • During runtime s1 and s2 can be objects of different types • It is not possible to assign the contents of a circle to a rectangle  Finally, the shape part of t is assigned to s2  Members (i.e., radius, sides a+b+c) used to compute the area of the shape are not swapped  Hence, only the name is swapped, and sort will not terminate, because the areas of the shapes are never swapped Th. Gschwind. Advanced Software Engineering with C++ Templates. 358

  4. Bubble Sort for vector<shape*> void sort(vector<shape*> &v) { if (v.size() < 2) return ; bool rerun; do { rerun = false; for (size_t i = 0; i < v.size()-1; ++i) { if (v[i]->get_area() > v[i+1]->get_area()) { swap(v[i], v[i+1]); // swap(*v[i], *v[i+1]); rerun = true; } } } while (rerun); }  We should have only exchanged the pointers in the vector  Providing swap for shapes, was probably misguided in the first place  It makes only sense to swap shapes of the very same type Th. Gschwind. Advanced Software Engineering with C++ Templates. 359

  5. Advanced Software Engineering with C++ Templates Liskov Substitution Principle Thomas Gschwind <thg at zurich dot ibm dot com>

  6. Liskov Substitution Principle Th. Gschwind. Advanced Software Engineering with C++ Templates. 361

  7. Squares and Rectangles  I had a colleague who was unsure whether to derive rectangle from square or vice-versa. What would you recommend to him? Implement a set of sample programs illustrating various options and your recommendation! The programs should demonstrate why your solution is better than the other solutions Th. Gschwind. Advanced Software Engineering with C++ Templates. 362

  8. Squares and Rectangles Shape inherits … Line Circle Triangle  Class hierarchy for a vector graphics program  We have an abstract class Shape from which various geometric shapes are being derived  Task: • Add the following classes: Square, Rectangle • Also add useful members like {get,set}_{width,height,length,size }, … Th. Gschwind. Advanced Software Engineering with C++ Templates. 363

  9. Liskov Substitution Principle If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behaviour of P is unchanged when o1 is substituted for o2 then S is a subtype of T. Put Simple: Every function/program must work the same when it is invoked with a subclass instead of the expected class. This is the responsibility of the subclasses! Th. Gschwind. Advanced Software Engineering with C++ Templates. 364

  10. Square  Rectangle class Rectangle { int w, h; public : Rectangle virtual void setWidth( int wi) { w=wi; } virtual void setHeight( int he) { h=he; } inherits }; Square class Square : public Rectangle { public : virtual void setWidth( int w) { Rectangle::setHeight(w); Rectangle::setWidth(w); } virtual void setHeight( int h) { setWidth(h); } }; Th. Gschwind. Advanced Software Engineering with C++ Templates. 365

  11. Square  Rectangle (cont’d)  What happens if we pass a Square to a function test expecting a Rectangle?  Can we expect the function test to know about Square?  Would it be OK if the function yields an unexpected outcome under the motto garbage-in garbage-out?  No! Because we claim that a Square is a Rectangle! void test(Rectangle &r) { Rectangle r.setWidth(5); r.setHeight(4); inherits assert((r.getWidth()*r.getHeight())==20); Square } Th. Gschwind. Advanced Software Engineering with C++ Templates. 366

  12. Square  Rectangle V2 class Rectangle { int w, h; public : Rectangle void setWidth( int wi) { w=wi; } void setHeight( int he) { h=he; } inherits }; Square class Square : public Rectangle { public : void setWidth( int w) { Rectangle::setHeight(w); Rectangle::setWidth(w); } void setHeight( int h) { setWidth(h); } }; Th. Gschwind. Advanced Software Engineering with C++ Templates. 367

  13. Square  Rectangle V2 (cont’d)  What happens if we pass a Square to a function test expecting a Rectangle?  The program works now as expected  However, since set_width/set_height are no longer virtual our Square is now a Rectangle ==> This is not the solution either void test(Rectangle &r) { Rectangle r.setWidth(5); r.setHeight(4); inherits assert((r.getWidth()*r.getHeight())==20); Square } Th. Gschwind. Advanced Software Engineering with C++ Templates. 368

  14. Rectangle  Square  Square has one field (height or width) Square  Rectangle adds another one for the other dimension inherits • Makes sense from a memory usage point of view Rectangle  Square has a method to set the length  Rectangle adds methods for height and width • Also makes sense from the methods they provide • A Square does not need set_height & set_width Th. Gschwind. Advanced Software Engineering with C++ Templates. 369

  15. Rectangle  Square class Square { Square int l; public : virtual void setLength( int le) { l=le; } inherits virtual int getLength() { return l; } Rectangle }; class Rectangle : public Square { // reuse length as height int w; public : virtual void setLength( int le) { Square::setLength(le); setWidth(le); } virtual void setHeight( int he) { Square::setLength(he); } virtual void setWidth( int wi) { w=wi; } }; Th. Gschwind. Advanced Software Engineering with C++ Templates. 370

  16. Rectangle  Square (cont’d)  We cannot pass a Square to the test function Square void test(Rectangle &r) { r.setWidth(5); r.setHeight(4); inherits Rectangle assert((r.getWidth()*r.getHeight())==20); }  What if test would take Squares? • No problem either, LSP fulfilled void test(Square &s) { s.setLength(5); s.setLength(4); assert((s.getLength()*s.getLength())==16); } Th. Gschwind. Advanced Software Engineering with C++ Templates. 371

  17. Rectangle  Square (cont’d)  Let us extend our Shape class hierarchy Square  Our customer requests a get_area() member int Square::get_area() { return l*l; } inherits int Rectangle::get_area() { return l*wi; } Rectangle void foo(Square &s) { assert((s.get_length()*s.get_length()) ==s.get_area()); } Th. Gschwind. Advanced Software Engineering with C++ Templates. 372

  18. Rectangle  Square (cont’d)  Let us extend our Shape class hierarchy Square  Our customer requests a get_area() member int Square::get_area() { return l*l; } inherits int Rectangle::get_area() { return l*wi; } Rectangle void test(Square &s) { assert((s.get_length()*s.get_length()) ==s.get_area()); } void oh_no_not_another_test() { Rectangle r(3,4); test(r); } Th. Gschwind. Advanced Software Engineering with C++ Templates. 373

  19. Square  Shape, Rectangle  Shape Shape inherits … Line Circle Square Rectangle Correct, don’t use deep class hierarchies just because it is “object - oriented” programming (is it?) or because it’s “cool” or “professional” (or whatever)! Th. Gschwind. Advanced Software Engineering with C++ Templates. 374

  20. Lessons Learned  Avoid code inheritance • People will nail you down on how the base class is implemented  If inheritance is needed define an interface • Now, only the documentation counts  Inherit the interface not the code  If code inheritance is needed, prefer the use of an interface plus use aggregation • Follow this advice especially when using Java • Yes, you need to type a bit more  If this is really (really?) not an option provide both an interface and a class to inherit from Th. Gschwind. Advanced Software Engineering with C++ Templates. 375

  21. Advanced Software Engineering with C++ Templates Exceptions Thomas Gschwind <thg at zurich dot ibm dot com>

  22. Exceptions  Error Handling  Exception Specification  Exception Discrimination  Cleaning up in C++ (a.k.a. finally )  Standard Exceptions Th. Gschwind. Advanced Software Engineering with C++ Templates. 377

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend