560 likes | 739 Views
Objects Managing a Resource. What is a Resource. Respects Release/Acquire protocol f iles (open/close ) memory allocation (allocate/free ) locks (acquire/release). What is a Resource. Objects when constructed , sometime acquire a resource.
E N D
What is a Resource • Respects Release/Acquire protocol • files (open/close) • memory allocation (allocate/free) • locks (acquire/release).
What is a Resource • Objects when constructed, sometime acquire a resource. • If designed carefully - acquire resource • otherwise (when unavoneoidable) will acquire several resources • When an object is destructed, its resources must be released.
Construction of objects • Allocating - Allocating enough memory to hold the object's state • Initialization - Initializing the internal state of the object. This involves 2 sub-steps: • Acquiring Resources - Acquiring the necessary resources which the object requires • Consistent state - Making sure that the initial state of the object is valid according to the class invariants
Construction of objects • RTE allocates the needed memory and calls the constructor of the class. • constructor is different from normal method invocation • object does not exist until the construction is finished. • do not accessthis of object in the constructor. • do not throw exceptions from the constructor…
destruction of the object • when an object is constructed, resources are allocated: • explicitly, by the object's constructor • implicitly –memory allocated to hold the object's state • resources should be deallocated. • programmer's responsibility of releasing the resources acquired by a process
destruction of the object • Releasing resources - releasing all of the resources acquired by the object during the object's lifetime and construction. • Releasing memory - releasing all the memory allocated for the object
Who destructs what? • destructing an object is shared between the RTE and the programmer: • programmer releases resources acquired by constructor or during the life time • RTE is responsible to release the memory allocated to hold the state of the object.
How to destruct? • object is implicitly destructed if object is allocated on stack. • when the program exits the scope of this object, the RTE will destruct the object. • object allocated on the heap is destructed explicitly, by the programmer • use delete operator on a pointer to the object.
Destruction order • RTE calls a special function of the object-destructor. • responsibility of the programmer to implement such a function, and release all resources acquired by the object during the object's lifetime. • RTE releases memory used to hold the object's statefrom stack or heap
LifeCycle of an Object • object is "born" after constructor successfully terminates. • object "retired" after destructor successfully terminates. • object is "alive“ following its construction and just before its destruction. • object is valid only as long as the object is alive.
Shape Collection Example • object that holds a collection of shapes. • will not create new shapes on its own • will receive previously constructed shapes to store • build the class…
C++ interface • Shape is an interface as all its functions are pure virtual[=0] in declaration • Pure virtual are functions that the compiler enforce us to implement. • An interface in C++ is implemented by using regular inheritance (C++ multiple inheritance) • /** ... */- special tokens recognized by doxygenfor auto documentation
Remarks • class Shape - is a forward declaration • typedef is used to define new types • Shapes is a type (just like int or any other class). • typedef is common to replace long types to short • std::vector<T> is a C++ template that holds a collection of type T.
Remarks • add() is receiving const Shape* - Shapes is of type vector<Shape*>=> our Shapes vector cannot directly hold pointers received by add function • parameter is const and the vector is not const • shapes are cloned and stored in collection • cant just be referenced by the collection. • fits well with collection description
Remarks • assert(Shape != 0) - as Add receives a pointer it must check for nullity. • check man assert • shapes_.size() must be const - why?
Memory leak • class hold clones of Shapes - responsible for releasing clones upon object destruction. • add appropriate dtorto ShapeCollection
Remarks • Destructors are declared virtual… inheritance… • If no good reason - declare each method as virtual. • We added the *i=0 for educational reasons.
Remarks • iterator is a pointer to an item of type T (here Shape*). • Dereferencing iterator returns Shape* • Dereferencing again to access a public method/member (**T)
What is the problem? • shapes passed to byVal is copied to s. • no copy-ctor implementation – default • default copy constructor performs a shallow copy of the object's state. • shapes_ vector of shapes is copied. • shapes on the heap pointed twice: from shapes, and from s!!!
What is the problem? • byValreturns - destructor is called • all the shapes of s1 are freed. • shapes still holds the pointers to shape addresses in heap
Assignment (=) problem • same problem arises with the assignment operator • every Class is a type - supports assignment. • given two ShapeCollections, s1 and s2: s1=s2 (s1=s1) exactly as you would do for an int or double.
Solution • define copy and assignment behavior • possible behaviors are: • Do not allow one or both of them • Explicitly implement behavior which is consistent with the class design
empty behavior should be implemented with every class you write. • if later you need copy or assignment - move to second solution. • How? declare copy constructor and assignment operator as private!
Copy • copy-ctor. • syntax: • given a const reference to another object of the same type (which you would not want to change) • copy its state to this object state
Shapes::const_iterator – an iterator to a const member of the Shapes vector.
Assignment • special method of the object:operator= • syntax: • given another object of the same type (which you would not want to change) • copy its state to this object's state • return an L-Value - meaning return the value of the left object. • make sure an object is not assigned to itself
need to define such behaviors on classes • someone will extend class in the future. • inheritance • techniques to reduce the overhead.
Managing Heap resource on Stack • Recall: • compiler calls ctor, dtor of objects declared on the stack automatically - when the scope is entered and exited • when object is copied, the compiler calls the copy constructor. • same for the assignment.
Memory management class • follow semantics of objects on the stack • create generic class to hold object's pointer • upon copy or assignment will not really copy the pointer but share it. • counthow many times the object is being referenced • not delete it (when dtoris called) until the last reference is gone.
shared_ptr • Boost - extension to the standard template library (STL), offering many advanced utilities
Remarks • much shorter and cleaner. • wrap the object of interest (shape*) - define a shared_ptr object on stack • shared_ptrcan then safely be given by value • in most cases shared_ptr is exactly what we need, rather than the copybehavior
How does shared_ptrworks? • did not supply copy or assignment behavior: • default–copy by val of all object's state. • collection's state is shapes_ of type vector<shared_ptr<Shape>> • copy constructor of vector is called • vector holds a collection of objects - shared_ptr<Shape> (shShape)
How does shared_ptr works? • Vector's copy-ctor copy by value - call shared_ptr copy-ctor – shares pointer to actual shape on the heap • shared_ptr holds a pointer and manages the reference count of this pointer • shared_ptrcopy-ctorand =operator - copy pointer by value • manage the reference counting, together with the destructor:
How does shared_ptr works? • When shared_ptr<T> t1 is assigned to shared_ptr<T> t2 share two resources: • the pointer managed by t1 is copied to t2, such that they now manage the same pointer. • t1 and t2 share a counter to count how many shared_ptrsare managing the same pointer. • copying the pointer and sharing the counter t2 increments the reference counter by one.
If t2 had a pointer prior to the copy, this pointer's reference count is first decreased by one. • A similar scenario takes place upon copy construction.
When the dtorof shared_ptr is called -reference count is decreased. • If count reaches zero, pointer managed by shared_ptr is deleted.
Exceptions During Construction • problem may arise during ctor - lead to an exception being thrown • exception during construction - object in an undetermined state. • Re-implementing the new operator. MastereC++
Exceptions During Construction • Catching exceptions in ctor itself. • two major problems: • construction needs to fail - no way of signaling this other than throwing an exception ourselves and • can not handle out of memory exception inside ctor - will be thrown before entering ctor (by the new operator).