fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <memory>
  5. #include <functional>
  6.  
  7. using namespace std;
  8.  
  9. //--------SMART POINTERS--------//
  10. struct A {
  11. int data;
  12. };
  13.  
  14. void foo(unique_ptr<A> p) {
  15. cout << p->data << endl;
  16. }
  17.  
  18. void foo2(shared_ptr<A> p) {
  19. cout << p->data << endl;
  20. }
  21.  
  22. int main() {
  23. //--------LAMBDAS--------//
  24. // o Return-type: generally evaluated by compiler, except for complex cases e.g. conditional statements. T.ex. "-> double"
  25. // o Parameters: similar to function parameters in every way.
  26. // o Capture-clauses: can capture external variables from enclosing scopes using
  27. // - [&]: capture all external variables by reference.
  28. // - [=]: capture all external variables by value.
  29. // - [a,&b]: capture 'a' by value and 'b' by reference.
  30.  
  31. vector<int> v = {1, 3, 4, 5, 6, 7, 8, 9};
  32. cout << "vector v:" << endl; //printing v
  33. for (auto x : v) { cout << x << " ";};
  34. cout << endl;
  35.  
  36. //Print odd numbers in vector v, const iterators
  37. cout << "odd numbers in vector v:" << endl;
  38. for_each(v.cbegin(), v.cend(), [](int x) {
  39. if (x % 2 != 0) {
  40. cout << x << " ";
  41. }
  42. });
  43. cout << endl;
  44.  
  45. //Multipliying all odd numbers by 2, non-const iterators
  46. for_each(v.begin(), v.end(), [](int &x) { //x as a reference
  47. if (x % 2 != 0) x *= 2;
  48. });
  49.  
  50. //Adding the size of the vector to all elements.
  51. int size = v.size();
  52. for_each(v.begin(), v.end(), [=](int &x) { //[=] capture 'size' by value, x as a reference
  53. x += size;
  54. });
  55.  
  56.  
  57. //Changes data outside the scope of the lambda by capturing with [ & ].
  58. int OUTSIDEDATA = 10;
  59. auto mofify_outsidedata = [&]() { //[&] capture data by reference
  60. OUTSIDEDATA += 5;
  61. };
  62.  
  63. mofify_outsidedata();
  64. cout << "OUTSIDEDATA: " << OUTSIDEDATA << endl;
  65.  
  66.  
  67.  
  68.  
  69. //--------SMART POINTERS--------//
  70. // o Unique_ptr: automatically manages allocated resources on heap.
  71. // o Shared_ptr:
  72. // o Weak_ptr:
  73.  
  74. //Define a unique_ptr to A inside an arbitrary scope and print the data
  75. unique_ptr<A> pa (new A{4});
  76. cout << pa -> data;
  77.  
  78. //Try calling foo with your unique_ptr. There is a compile error because you are calling by value, trying to copy the pointer.
  79. foo(std::move(pa)); //move ownership of resource from pa to p inside function
  80.  
  81. // //--------SHARED PTR--------//
  82. shared_ptr<A> sa(new A{5});
  83. cout << sa -> data;
  84.  
  85. //Call foo2 first normally and then by moving. Run valgrind on both executables. Is there a memory leak?
  86. //NO LEAKS SHOWN BY FSANITIZE FLAG: -fsanitize=address
  87. //foo2(sa); // check with valgrind
  88. foo2(std::move(sa)); // check with valgrind
  89.  
  90.  
  91. // //--------WEAK POINTER--------//
  92. // //Constructing a weak pointer as a shared pointer generates a compile error
  93. // weak_ptr<A> wa(new A {5});
  94.  
  95. // //Construct a weak pointer to the previous shared pointer and try print the data. There will be a compile error.
  96. // weak_ptr<A> wa = sa;
  97. // cout << wa->data;
  98.  
  99. // //Use the lock member function to print the data field.
  100.  
  101. // //--------CIRCULAR DEPENDENCIES--------//
  102. // //Given BhasA and AhasB
  103. // struct BhasA;
  104. // struct AhasB {
  105. // AhasB(shared_ptr<BhasA> b) : m_b(b) {
  106. // resource = new int[4];
  107. // };
  108.  
  109. // shared_ptr<BhasA> m_b;
  110. // int * resource;
  111.  
  112. // ~AhasB() {delete [] resource;}
  113. // AhasB(const AhasB &) = delete;
  114. // void operator=(const AhasB &) = delete;
  115. // };
  116.  
  117. // struct BhasA {
  118. // BhasA() {resource = new int[4];};
  119.  
  120. // shared_ptr<AhasB> m_a;
  121. // int * resource;
  122.  
  123. // ~BhasA() {delete [] resource;}
  124. // BhasA(const BhasA &) = delete;
  125. // void operator=(const BhasA &) = delete;
  126. // };
  127. // //Declare one instance each of AhasB and BhasA and link them.
  128. // shared_ptr<BhasA> bptr(new BhasA);
  129. // shared_ptr<AhasB> aptr(new AhasB(bptr));
  130.  
  131. // bptr->m_a=aptr;
  132. // //There is a memory leak when you run valgrind on the code because of the circular dependency. Fix the memory leak by changing one of the shared_ptr members to a weak pointer.
  133.  
  134.  
  135.  
  136. // //--------USING A DELETER--------//
  137. // //Given B
  138. // struct B {
  139. // B() { b = new int[4]; }
  140.  
  141. // int * b;
  142. // ~B() { delete [] b; }
  143. // B(const B &) = delete;
  144. // void operator= (const B & ) = delete;
  145. // };
  146. // //Unless the compiler detects it, there will a memory leak when declaring a unique_ptr as below. Verify the memory leak with valgrind.
  147. // unique_ptr<B> pb(new B[2]);
  148.  
  149.  
  150. // //The memory leak is because the unique_ptr assumes it points to a single object not to an array.
  151. // //In order to fix the memory leak you need to create a function that does a correct deletion of the objects.
  152. // //Write a lambda function that does a correct deletion of the array
  153.  
  154. // auto deleter = // YOUR LAMBDA HERE
  155. // unique_ptr<B, decltype(deleter)> pb2(new B[2], deleter);
  156.  
  157. // //If you know the signature of your lambda function you can declare it with the function keyword directly instead of using auto
  158. // function<void(B*)> fb = // YOUR LAMBDA
  159.  
  160. // //It is thus possible to declare the unique_ptr in one row
  161. // unique_ptr<B, function<void(B*)> > pb1(new B[2], // YOUR LAMBDA
  162.  
  163.  
  164. // //Note: In later standards its possible to specify the kind of pointer in the template parameter
  165. // unique_ptr< B[] > pb(new B[2]); // Note B[]
  166.  
  167.  
  168. return 0;
  169. }
Success #stdin #stdout 0.01s 5284KB
stdin
1
2
10
42
11
stdout
vector v:
1 3 4 5 6 7 8 9 
odd numbers in vector v:
1 3 5 7 9 
OUTSIDEDATA: 15
44
55