Download presentation

Presentation is loading. Please wait.

Published byGrady Weast Modified about 1 year ago

1
K. Stirewalt CSE 335: Software Design Synthetic OOD concepts and reuse Lecture 4: Separation of concerns Topics: –Complex concern: Memory management – Example: Complex operations on composite structures – Problem: Memory leaks – Solution: Reference counting

2
K. Stirewalt CSE 335: Software Design Motivation Suppose we define a function: Expr* mkExpr(void) { Expr* l1 = new Literal(2); Expr* v = new Variable(“x”); Expr* t1 = new Add(l1,v); Expr* l2 = new Literal(2); Expr* t2 = new Multiply(l2,t1); }

3
K. Stirewalt CSE 335: Software Design Problem Suppose a client program executes the code:... Expr* e = mkExpr(); e->print(cout); delete e;... What happens? How could we ensure that when a composite object is deleted, its parts are also deleted?

4
K. Stirewalt CSE 335: Software Design Solution class Expr {... virtual ~Expr() {} }; class BinaryExpr : public Expr {... ~BinaryExpr() { delete(leftOperand); delete(rightOperand); }... };

5
K. Stirewalt CSE 335: Software Design Or is it? Often desirable for two or more composite objects to share the same component Example: Expr* l = new Literal(2); Expr* v = new Variable(“x”); Expr* t1 = new Add(l,v); Expr* t2 = new Multiply(l,t1); Here, object l is the child of two composite objects, t1 and t2. Will our memory-reclamation scheme work now?

6
K. Stirewalt CSE 335: Software Design Deleting composites that share parts Not safe for destructor of a composite class to delete its children if these objects might be children of multiple composite objects Solution: design a protocol that tracks references to objects and that deletes an object only when its reference count reaches 0. –Clients never call delete –Objects call delete on themselves! –Clients must explicitly notify objects when references to these objects are assigned or overwritten

7
K. Stirewalt CSE 335: Software Design Abstract ref-counting class class RCObject { public: void addRef() { ++refCount; } void removeRef() { if(--refCount <= 0) delete this; } protected: RCObject() : refCount(0) {} virtual ~RCObject() {} private: int refCount; };

8
K. Stirewalt CSE 335: Software Design Example Modify class Expr as follows: class Expr : public RCObject {... }; Subsequently, every class that derives from Expr will inherit reference counting infra- structure

9
K. Stirewalt CSE 335: Software Design Example Modify BinaryExpr as follows: class BinaryExpr : public Expr {... BinaryExpr( Expr* l, Expr* r ) : leftOperand(l), rightOperand(r) { l->addRef(); r->addRef(); }... ~BinaryExpr() { l->removeRef(); r->removeRef(); } };

10
K. Stirewalt CSE 335: Software Design Example (continued) Now we write a function that creates an expression: Expr* createExpression(void) { Expr* l = new Literal(2); Expr* v = new Variable(“x”); Expr* t1 = new Add(l,v); Expr* t2 = new Multiply(l,t1); return t2; } Requires client to increment refCount of root object (pointed to here by t2 before it goes out of scope)

11
K. Stirewalt CSE 335: Software Design Step 1 Expr* createExpression(void) { Expr* l = new Literal(2); Expr* v = new Variable(“x”); Expr* t1 = new Add(l,v); Expr* t2 = new Multiply(l,t1); return t2; } l : Literal refCount=0

12
K. Stirewalt CSE 335: Software Design Step 2 Expr* createExpression(void) { Expr* l = new Literal(2); Expr* v = new Variable(“x”); Expr* t1 = new Add(l,v); Expr* t2 = new Multiply(l,t1); return t2; } l : Literal refCount=0 v : Variable refCount=0

13
K. Stirewalt CSE 335: Software Design Step 3 Expr* createExpression(void) { Expr* l = new Literal(2); Expr* v = new Variable(“x”); Expr* t1 = new Add(l,v); Expr* t2 = new Multiply(l,t1); return t2; } l : Literal refCount=1 v : Variable refCount=1 t1 : Add refCount=0

14
K. Stirewalt CSE 335: Software Design Step 4 Expr* createExpression(void) { Expr* l = new Literal(2); Expr* v = new Variable(“x”); Expr* t1 = new Add(l,v); Expr* t2 = new Multiply(l,t1); return t2; } l : Literal refCount=2 v : Variable refCount=1 t1 : Add refCount=1 t2 : Multiply refCount=0

15
K. Stirewalt CSE 335: Software Design Example (continued) Client code then uses as follows:... Expr* e = createExpression(); e->addRef(); // new line e->print(cout); e->removeRef(); // rather than delete(e)...

16
K. Stirewalt CSE 335: Software Design Adding reference to returned object e->addRef(); e->print(cout); e->removeRef(); l : Literal refCount=2 v : Variable refCount=1 t1 : Add refCount=1 t2 : Multiply refCount=1 e

17
K. Stirewalt CSE 335: Software Design Printing expression... e->addRef(); e->print(cout); e->removeRef(); l : Literal refCount=2 v : Variable refCount=1 t1 : Add refCount=1 t2 : Multiply refCount=1 e

18
K. Stirewalt CSE 335: Software Design Removing ref: Step 1 e->addRef(); e->print(cout); e->removeRef(); l : Literal refCount=1 v : Variable refCount=1 t1 : Add refCount=1 t2 : Multiply refCount=0 e

19
K. Stirewalt CSE 335: Software Design Removing ref: Step 2 e->addRef(); e->print(cout); e->removeRef(); l : Literal refCount=1 v : Variable refCount=1 t1 : Add refCount=0 t2 : Multiply refCount=0 e

20
K. Stirewalt CSE 335: Software Design Removing ref: Step 3 e->addRef(); e->print(cout); e->removeRef(); l : Literal refCount=0 v : Variable refCount=1 t1 : Add refCount=0 t2 : Multiply refCount=0 e

21
K. Stirewalt CSE 335: Software Design Removing ref: Step 4 e->addRef(); e->print(cout); e->removeRef(); l : Literal refCount=0 v : Variable refCount=1 t1 : Add refCount=0 t2 : Multiply refCount=0 e

22
K. Stirewalt CSE 335: Software Design Removing ref: Step 5 e->addRef(); e->print(cout); e->removeRef(); v : Variable refCount=0 t1 : Add refCount=0 t2 : Multiply refCount=0 e

23
K. Stirewalt CSE 335: Software Design Removing ref: Step 6 e->addRef(); e->print(cout); e->removeRef(); v : Variable refCount=0 t1 : Add refCount=0 t2 : Multiply refCount=0 e

24
K. Stirewalt CSE 335: Software Design Removing ref: Step 7 e->addRef(); e->print(cout); e->removeRef(); t1 : Add refCount=0 t2 : Multiply refCount=0 e

25
K. Stirewalt CSE 335: Software Design Removing ref: Step 8 e->addRef(); e->print(cout); e->removeRef(); t2 : Multiply refCount=0 e

26
K. Stirewalt CSE 335: Software Design Conceptual (but flawed) alternative implementation of createExpression() Expr* createExpression(void) { Expr* l = new Literal(2); l->addRef(); Expr* v = new Variable(“x”); v->addRef(); Expr* t1 = new Add(l,v); t1->addRef(); Expr* t2 = new Multiply(l,t1); t2->addRef(); l->removeRef(); v->removeRef(); t1->removeRef(); t2->removeRef(); // What happens here??? return t2; }

27
K. Stirewalt CSE 335: Software Design “Mixin” classes RCObject is an example of a “mixin” class –So-called because designed to encapsulate orthogonal functionality that may be “mixed into” classes in an existing hierarchy –Mixin classes are always abstract –May use multiple inheritance to incorporate functionality in a mixin class if base class does not need it or if base class needs functionality from multiple mixin classes

Similar presentations

© 2017 SlidePlayer.com Inc.

All rights reserved.

Ads by Google