Advertisement
bogolyubskiyalexey

hse seminar: smart pointers

Oct 6th, 2020
921
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.93 KB | None | 0 0
  1. #include <memory>
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5.  
  6.  
  7. template<typename T>
  8. class MySharedPtr {
  9. private:
  10.     void decrement_cnt() {
  11.         if (cnt == nullptr) {
  12.             return;
  13.         }
  14.         --(*cnt);
  15.         if (*cnt == 0) {
  16.             delete ptr;
  17.             delete cnt;
  18.             ptr = nullptr;
  19.             cnt = nullptr;
  20.         }
  21.     }
  22.    
  23.     void increment_cnt() {
  24.         if (cnt != nullptr)
  25.             ++(*cnt);
  26.     }
  27.    
  28.     T* ptr = nullptr;
  29.     size_t* cnt = nullptr;
  30.  
  31. public:
  32.     MySharedPtr() = default;
  33.  
  34.     MySharedPtr(T* _ptr) : ptr(_ptr) {
  35.         if (ptr == nullptr) {
  36.             return;
  37.         }
  38.         cnt = new size_t(1);
  39.     }
  40.    
  41.     MySharedPtr(const MySharedPtr& other) {
  42.         ptr = other.ptr;
  43.         cnt = other.cnt;
  44.         increment_cnt();
  45.     }
  46.    
  47.     MySharedPtr(MySharedPtr&& other) {
  48.         std::swap(ptr, other.ptr);
  49.         std::swap(cnt, other.cnt);
  50.     }
  51.    
  52.     MySharedPtr& operator=(const MySharedPtr& other) {
  53.         if (this != &other) {
  54.             decrement_cnt();
  55.             ptr = other.ptr;
  56.             cnt = other.cnt;
  57.             increment_cnt();
  58.         }
  59.         return *this;
  60.     }
  61.    
  62.     MySharedPtr& operator=(MySharedPtr&& other) {
  63.         // может быть стоит написать std::swap как в конструкторе MySharedPtr(MySharedPtr&&)
  64.         if (this != &other) {
  65.             decrement_cnt();
  66.             ptr = other.ptr;
  67.             cnt = other.cnt;
  68.             other.ptr = nullptr;
  69.             other.cnt = nullptr;
  70.         }
  71.         return *this;
  72.     }
  73.    
  74.     size_t use_count() const {
  75.         if (cnt == nullptr) {
  76.             return 0;
  77.         }
  78.         return *cnt;
  79.     }
  80.    
  81.     const T& operator*() const {
  82.         return *ptr;
  83.     }
  84.    
  85.     T& operator*() {
  86.         return *ptr;
  87.     }
  88.    
  89.     T* operator->() {
  90.         return ptr;
  91.     }
  92.    
  93.     ~MySharedPtr() {
  94.         decrement_cnt();
  95.     }
  96. };
  97.  
  98.  
  99.  
  100. struct Resource {
  101.     int id;
  102. };
  103.  
  104. class ResourceManager {
  105. public:
  106.     ResourceManager(size_t maxCount): allResources(maxCount) {}
  107.    
  108.     shared_ptr<Resource> create() {
  109.         for (auto& resource : allResources) {
  110.             if (resource.expired()) {
  111.                 std::shared_ptr<Resource> ptr(new Resource);
  112.                 resource = ptr;
  113.                 return ptr;
  114.             }
  115.         }
  116.         return nullptr;
  117.     }
  118.     size_t current_resources_count() const {
  119.         size_t result = 0;
  120.         for (const auto& resource : allResources) {
  121.             if (!resource.expired()) {
  122.                 ++result;
  123.             }
  124.         }
  125.         return result;
  126.     }
  127. private:
  128.     vector<weak_ptr<Resource>> allResources;
  129. };
  130.  
  131. int main() {
  132.     /*std::weak_ptr<int> wPtr;
  133.     {
  134.         std::shared_ptr<int> ptr(new int(19));
  135.         wPtr = ptr;
  136.         std::cout << wPtr.expired() << " " << wPtr.use_count() << std::endl;
  137.         {
  138.             std::shared_ptr<int> ptr2 = ptr;
  139.             std::cout << wPtr.expired() << " " << wPtr.use_count() << std::endl;
  140.         }
  141.         std::cout << wPtr.expired() << " " << wPtr.use_count() << std::endl;
  142.         shared_ptr<int> ptr3 = wPtr.lock();
  143.         std::cout << wPtr.expired() << " " << wPtr.use_count() << std::endl;
  144.     }
  145.     std::cout << wPtr.expired() << " " << wPtr.use_count() << std::endl;
  146.     return 0;*/
  147.    
  148.     ResourceManager manager(3);
  149.     std::cout << "current: " << manager.current_resources_count() << std::endl;
  150.    
  151.     auto a = manager.create();
  152.     auto b = manager.create();
  153.     auto c = manager.create();
  154.     auto d = manager.create(); // nullptr
  155.     c = nullptr;
  156.     std::cout << "c: " << c.use_count() << std::endl;
  157.     std::cout << "current: " << manager.current_resources_count() << std::endl; // 2
  158.    
  159.     auto e = manager.create(); // e != nullptr
  160.     std::cout << "current: " << manager.current_resources_count() << std::endl; // 3
  161. }
  162.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement