Last Class Template metaprogramming and typetraits Multiple inheritance
- Slides: 53
Last Class • Template meta-programming and type-traits • Multiple inheritance • Diamond of dread ! • Virtual base class • C-tors order • Exceptions • throw(), try, catch, etc… • Inheritance • stack unwinding • terminate() • RTTI • Polymorphic type 1
Throw Temporary Object, Catch by Value //Compilation error: void f(T& t) {} f(T()); //No compilation error: try { throw T(); } catch (T& t) { } 2 Special feature of • exceptions mechanism, that the thrown object is guaranteed to have a lifetime of the exception handling. Implemented differently • on different compilers
c++ style casting �static_cast<type>(expression) �const_cast<type>(expression) �reinterpret_cast<type>(expression) �dynamic_cast<type>(expression) 3
‘static_cast’ and ‘dynamic_cast’ int i = static_cast<int>(12. 45); Shape* s = container. pop(); Circle* c = dynamic_cast<Circle*>(s); 4
Important point about exceptions struct B { B() {cout << "in B's c-tor" << endl; } ~B() {cout << "in B's d-tor" << endl; } }; struct A : public B { A() {cout << "in A's c-tor" << endl; } ~A() {cout << "in A's d-tor" << endl; } }; void main() { try { A* p=new A; throw(2); } catch (. . . ) { } } 5 Oh ! NO
Solutions • set_terminate(Take. Care. Of. Everything) • catch(…) • maybe there are more creative ideas • auto_ptr (smart pointers) 6
Smart Pointers
Memory Management • One of the major issues in writing C/C++ code is managing dynamically allocated memory • Biggest question is how to ensure that allocated memory will be freed when it is no longer in use • Also important – allocate and free efficiently, in space (fragmentation) and time (new is expensive). [out of our scope] 8
Strategies to memory management 1) fixed ownership 2) dynamic ownership compile 2) run time 1) 3) reference counting • 9 non reference counting garbage collection (used in. NET) will not be discussed
Strategy #1: Fixed Ownership • Allocated pointer belongs to the entity (function or objects) that created it • That entity is responsible for freeing the pointer void foo() { char* mem = new char[1000]; . . . delete [] mem; } 10
Example: String class String { public: String( char const *str ) { int l = strlen(str); _data = new char[l]; memcpy(_data, str, l); } ~String() { delete [] _data; } private: char* _data; 11 }; • The memory for char* represented by String is owned by the object • Class encapsulates details of memory management • With careful implementation, this class is memory-tight
Strategy #2: Dynamic ownership (compile time) • Object has an owner • However, owner changes through specific function calls Example: strdup(s) allocates new memory and returns a pointer to it in the return value, strdup does not release the memory #include <string. h> char *strdup(const char *s); Very hard to keep track of responsibility. 12
Ownership transfer and interface design Design principle: The allocator of a resource is responsible to free it. • Reduces memory leaks due to interface problems 13
Example: design choices Read. Line – read a line of input All of the above options are problematic! char* Read. Line() – returns pointer to newly allocated memory – user has to free it char* Read. Line() – returns pointer to static buffer – user has to copy line to another buffer void Read. Line(char* Buffer, int len) – uses a user supplied buffer – Read. Line cannot resize buffer 14
Strategy #3: Dynamic ownership (run time) • In some cases we cannot know who will own a pointer • In other cases, we do not want the programmer to remember who owns what • Can we use an object that “remembers” who owns the object? 15
“Dumb” Pointers Suppose T is a class T* is a “dumb pointer” supplied by compiler It remembers the address of the object and allows us to access it, but nothing else. Can we build smarter pointers, that will be able to do more than that? • Memory clean-up • Proxy • … 16
The Pointer Interface To implement a pointer-like object we need (approximately): pointer: : pointer( T*) pointer: : pointer( pointer const& ) pointer& pointer: : operator=( pointer const& ) T& pointer: : operator*() T* pointer: : operator->() If it looks like a pointer and feels like a pointer… 17
“Smart” Pointers The STL contains two smart pointers: 1. auto_ptr. It warps a pointer, and when destructed, frees the pointed memory. Copying is ownership transfer - only one auto_ptr points to each memory location. Depricated in c++11. 2. unique_ptr – replaces auto_ptr in c++11 3. shared_ptr – "reference counting" pointer. multiple pointers can point to one location, when the last one is destructed the memory is freed. Introduced in tr 1 and c++11 added functionality 18
auto_ptr #include <memory> struct bar { }; void foo() { auto_ptr<bar> my. Bar(new bar); // use my. Bar as a pointer } // my. Bar is deleted automatically 19
Auto_ptr in exceptions Auto_ptrs provide clean mechanism to deal with exception void foo() { try { auto_ptr<bar> my. Bar = new bar; apple(); //apple might throw an execption } catch (exception& e) {} } // my. Bar is deleted automatically // even if an exception is thrown by apple 20
Auto_ptr auto_ptr is like a pointer, but not exactly: void foo() { auto_ptr<bar> my. Bar(new bar); if(true) { auto_ptr<bar> my. Other. Bar = my. Bar; } } //calls dectrutors of my. Bar, my. Other. Bar What happens in this example? 21
Transfer of Ownership To avoid multiple deletes, auto_ptr ensures that: only one auto_ptr points to a certain object The statement auto_ptr<bar> my. Other. Bar = my. Bar; transfer the ownership from my. Bar to my. Other. Bar How do we achieve this? 22
auto_ptr details 23 No const? suspicious… auto_ptr( auto_ptr& rhs ) : _ptr( rhs. release() ) { } auto_ptr& operator=( auto_ptr& rhs ) { reset( rhs. release() ); return *this; Why do we do this? } What does it remind us? void reset(T* p = NULL) { if( _ptr != p ) delete _ptr; _ptr = p; } T* release() { T* tmp = _ptr; _ptr = NULL; return tmp; }
auto_ptr and stack unwinding auto_ptr is basically a wrap to a pointer, so that it is automatically deleted when we leave the scope. My. Class* f(. . . ) { auto_ptr<My. Class> p(new My. Class()); . . . return p. release(); } If an exception occurs prior to return, and is caught, the instance of My. Class will be automatically deleted by p’s destructor 24
auto_ptr summary 1. Provide mechanism for transfer of ownerships 2. Does not replace the need for pointers (Only one auto_ptr can point a resource at a time) 3. Can be dangerous - Copy ctor and op. = are disguised move! 2. DO NOT use in STL containers (because of the unusual copying behavior) 1. 4. Further reading: http: //msdn. microsoft. com/enus/library/hh 279674. aspx http: //www. cprogramming. com/tutorial/auto_ptr. html 25
auto_ptr => unique_ptr • auto_ptr is depricated • replaced by unique_ptr in c++11 – gives ownership errors in compile time (no operator=) • Can be used in stl containers • Uses move semantics and rvalue reference (hopefully we will talk about it next week) • You can read more at: http: //www. informit. com/guides/content. aspx? g=cplus&seq. Num=400 26
unique_ptr Clearer syntax: auto_ptr: std: : auto_ptr<int> p(new int); std: : auto_ptr<int> p 2 = p; unique_ptr: std: : unique_ptr<int> p(new int); std: : unique_ptr<int> p 2 = std: : move(p); 27
unique_ptr in stl containers Can be used in containers: vector<unique_ptr<int> > v; unique_ptr<int> p(new int); v. push_back(move(p)) 28
Strategy #4: Reference Counting • In some cases, we do not want to establish ownership. • Managing ownership within forces us to make unnecessary copies. • Can we get away with memory management without ownership? • The general mechanism of reference counting provides one solution 29
std: : c++11: : shared_ptr • Uses "shared memory semantics" – (i. e. , in most cases – reference counting). • In addition to pointing to the object all instances keep a pointer to a counter. • The counter is: • Increased on creation • Increased on copy • Decreased on delete • When counter reaches 0 the destructor is called. 30
std: : c++11: : shared_ptr Very simplistic shared pointer: template <typename T> class SPtr { private: int* _cnt; T* _p; Not complete and not precise public: T operator*() { return *_p; } const T& operator*() const; { return *_p; } SPtr(const T*& p): _p(p), _cnt(new int(1)) {} SPtr(const SPtr& o) {*this=o; } 31 SPtr operator=(const SPtr& o) { _p=o. _p; _cnt=o. _cnt; (*_cnt)++; } ~SPtr() { (*_ cnt)--; if ((*_ cnt)==0) { delete _p; delete _cnt; } } //. . . }
std: : c++11: : shared_ptr SPtr(const T*& p): _p(p), _cnt(new int(1)) {} SPtr(const SPtr& o) {*this=o; } SPtr operator=( const SPtr& o) { _p=o. _p; _cnt=o. _cnt; (*_cnt)++; } 32 ~SPtr() { (*_ cnt)--; if ((*_ cnt)==0) { delete _p; delete _cnt; } } Not complete and not precise
Using shared_ptr int main () { shared_ptr<Dog> p. D(new Dog("Gunner")); //count=1 { shared_ptr<Dog> p. D 2 = pd; //count = 2 } //count = 1 } //count = 0 34
shared_ptr Do not initialize 2 shared ptrs from the same raw pointer: Dog* p = new Dog(); shared_ptr<int> p 1(p); // count = 1 shared_ptr<int> p 2=p 1; // count = 2 But still: delete p; //will cause double delete 35
Memory wasting std: : string a = "foo bar"; std: : string b = a; std: : string c = a; The resulting memory structure: a: foo bar b: foo bar c: foo bar stack 36 heap
General Reference Counting Space can be preserved if we use reference counting : a: b: c: 37 3 foo bar
Copy On Write (COW) What happens when we change one of the objects? a = "foo bar 2"; All the objects change Solution: “Copy on Write” (COW) – make a copy of an object when it is modified - “lazy evaluation”. a: b: c: 38 3 foo bar
COW is actually an optimization technique • example: std: : string x("Hello"); 39 std: : string y = x; // x and y use the same buffer y += ", World!"; // now y uses a different buffer // x still uses the same old buffer
When to use what ? auto_ptr/unique_ptr Ownership transfer: �simple yet problematic �Good for local variables �DON’T put (auto_ptr) in STL containers! shared_ptr (reference counted): �Simple, memory safe, efficient+�Very good for large objects, and STL containers 40
More about smart pointers Many useful libraries use smart pointers for their memory management: �Boost (integrated later c++11): �http: //www. boost. org/libs/smart_ptr. htm �From wikipedia: �http: //en. wikipedia. org/wiki/Smart_pointer 41
int main() { Wrapper<int> pass_grade(55); Wrapper<int> excellent_grade(100); Wrapper<int> super_grade(100); cout << (pass_grade == excellent_grade) << " "; pass_grade=pass_grade; Wrapper<int> best_grade(excellent_grade); cout << (best_grade == excellent_grade) << " "; best_grade=super_grade; cout << (super_grade==best_grade) << " "; excellent_grade=95; cout << (best_grade == excellent_grade) << " "; Wrapper<int> another_grade(pass_grade); another_grade=excellent_grade; cout << (another_grade == excellent_grade) << " "; cout << (another_grade == 95) << edl; return 0; } 43 member- אילו נדרשות functions למחלקה הטמפלייטית בכדי שתוכנית Wrapper הנ"ל תעבור main- ה ? קומפילציה
נדרשות למחלקה הטמפלייטית member-functions אילו ? הנ"ל תעבור קומפילציה main- בכדי שתוכנית ה Wrapper(const T& x) Wrapper(Wrapper& other) Wrapper& operator=(const T& data) bool operator==(const Wrapper& other. Data) 44
template <class T> class Wrapper { public: Wrapper(const T& x): _p(new T(x)), _counter(new int(1)) {} Wrapper(Wrapper& other) { _p=other. _p; _counter=other. _counter; (*_counter)++; } ~Wrapper() { (*_counter)--; if (*_counter==0) { delete _p; delete _counter; } } 46
47 Wrapper& operator=(Wrapper& other) { if (this != &other) { (*_counter)--; if (*_counter==0) { delete _p; delete _counter; } _p=other. _p; _counter=other. _counter; (*_counter)++; } return *this; } Wrapper& operator=(const T& data) { if (*_p!=data) { (*_counter)--; if (*_counter==0) delete _p; delete _counter; _p=new T(data); _counter=new int(1); } return *this; }
bool operator==(const Wrapper& other) { return (*_p==*other. _p); } bool operator==(const T& other. Data) { return (*_p==other. Data); } private: T* _p; int* _counter; }; 48
few small things 50
mutable • mutable means that a variable can be changed by a const function (even if the object is const) • Can be applied only to non-static and non-const data members of a class X { public: X(): m_flag(true){} bool Get. Flag() const { m_access. Count++; return m_flag; } private: bool m_flag; mutable int m_access. Count; }; int main() { const X x; x. Get. Flag(); } 51
Pointer to member function struct X { virtual int& Val 1() { return _val 1; } int& Val 2() { return _val 2; } int _val 1, _val 2; X(): _val 1(1), _val 2(2){} }; int main() { X x; cout << x. _val 1 << " " << x. _val 2 << endl; Callback(x, &X: : Val 1, 5); cout << x. _val 1 << " " << x. _val 2 << endl; template <class T> void Callback(X& x, T& (X: : *func)(), T val) { T a=(x. *func)(); cout << "In callback first: a=" << a << endl; Callback(x, &X: : Val 2, 7); cout << x. _val 1 << " " << x. _val 2 << endl; } (x. *func)()=val; a=(x. *func)(); cout << "In callback second: a=" << a << endl; } 52
Method hiding struct B { (virtual) void f(bool i) {cout << "bool" << endl; } }; struct D : public B { void f(int b) {cout << "int" << endl; } }; int main(){ D d; d. f(true); d. B: : f(true); d. f(3); d. B: : f(3); } 53
Polymorphism with references struct B { virtual void f() { cout << "B" << endl; } }; struct D : public B { void f() { cout << "D" << endl; } }; 54 int main() { D d; B b=d; b. f(); } int main() { D d; B& b=d; b. f(); }
- Template meta programming
- Metaprogramming
- C# metaprogramming binja
- Andrea morichetta
- Oop
- Multiple baseline across settings
- Example of mimd
- Theme of ch the last lesson
- Last class for today
- What did we learn last class
- Last class of the day
- Noun clauses embedded questions
- Noun clauses embedded questions
- Langkah-langkah mengaktifkan microsoft publisher
- Non nuclear inheritance
- Advantages of inheritance
- Extranuclear inheritance
- Section 12-1 chromosomes and inheritance
- Chapter 11 complex inheritance and human heredity test
- Encapsulation inheritance and polymorphism
- Inheritance encapsulation
- Reproduction and inheritance
- Difference between mendelian and non mendelian inheritance
- Mendel's first and second law of inheritance
- Harry potter and the inheritance of sex
- The cellular basis of reproduction and inheritance
- Introduction to ooad
- Difference between abstract class and concrete class
- 7 rights of medication administration in order
- Static vs dynamic class loading in java
- How is function overloading different from template class
- Class list log
- Class tree template
- Template class t t func(t a)
- Prisma inheritance
- Objek diagram
- Priority inheritance
- Inheritance scala
- Inheritance of loss
- Craniodiaphyseal dysplasia
- Rails sti vs polymorphic
- X linked gene punnett square
- Sexlinked inheritance
- Inheritance of quantitative traits
- Proverbs 13 1
- Tujuan inheritance
- Pengertian dari inheritance
- X-linked recessive pedigree chart
- Complete dominance pattern of inheritance
- Private inheritance
- Non mendelian inheritance
- Human inheritance modern genetics answer key
- Genetics graphic organizer
- Modern genetics human inheritance answer key