1. C++ / Говнокод #24565

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    #include <iostream>
    #include <memory>
    #include <thread>
    #include <chrono>
    #include <mutex>
     
    struct Base
    {
        Base() { std::cout << "  Base::Base()\n"; }
        // Note: non-virtual destructor is OK here
        ~Base() { std::cout << "  Base::~Base()\n"; }
    };
     
    struct Derived: public Base
    {
        Derived() { std::cout << "  Derived::Derived()\n"; }
        ~Derived() { std::cout << "  Derived::~Derived()\n"; }
    };
     
    void thr(std::shared_ptr<Base> p)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::shared_ptr<Base> lp = p; // thread-safe, even though the
                                      // shared use_count is incremented
        {
            static std::mutex io_mutex;
            std::lock_guard<std::mutex> lk(io_mutex);
            std::cout << "local pointer in a thread:\n"
                      << "  lp.get() = " << lp.get()
                      << ", lp.use_count() = " << lp.use_count() << '\n';
        }
    }
     
    int main()
    {
        std::shared_ptr<Base> p = std::make_shared<Derived>();
     
        std::cout << "Created a shared Derived (as a pointer to Base)\n"
                  << "  p.get() = " << p.get()
                  << ", p.use_count() = " << p.use_count() << '\n';
        std::thread t1(thr, p), t2(thr, p), t3(thr, p);
        p.reset(); // release ownership from main
        std::cout << "Shared ownership between 3 threads and released\n"
                  << "ownership from main:\n"
                  << "  p.get() = " << p.get()
                  << ", p.use_count() = " << p.use_count() << '\n';
        t1.join(); t2.join(); t3.join();
        std::cout << "All threads completed, the last one deleted Derived\n";
    }

    https://en.cppreference.com/w/cpp/memory/shared_ptr

    Объясните почему "reset" не грохнул инстанс в других потоках?

    Запостил: guestinxo, 02 Августа 2018

    Комментарии (22) RSS

    • Переведи на "SQL", ибо я не понимаю "C++".
      Ответить
    • https://ru.cppreference.com/w/cpp/thread/thread/thread

      > 3) Создает новый объект std::thread и связывает его с потоком выполнения. Первый конструктор копирует все аргументы args... в локальную память потока, как функция:

      Ты передаешь туда shared_ptr, который конструктор thread копирует.

      А shared_ptr удаляет указываемый объект, когда на него больше нету ссылок.
      https://ru.cppreference.com/w/cpp/memory/shared_ptr
      Ответить
    • Собственно, вызов reset просто уменьшает количество ссылок на одну, а у тебя остается еще 3. В каждом экземпляре thread.
      Но твой объект Base будет удален, как только деструтурируются все 3 этих объекта.
      Ответить
      • показать все, что скрытоvanished
        Ответить
        • Но он должен вести себя соответственно семантике подсчета ссылок.
          А именно сбрасывать use_count на значение меньшее на единицу. Как это происходит при завершении потоков.

          Почему же use_count после вызова reset устанавливается в 0 -- непонятно.
          Ответить
    • Тут более интересно
      // Note: non-virtual destructor is OK here

      Но это тоже понятно. На самом деле мы можем вообще написать
      class Base; // Forward declaration
      class A
      {
      public:
        std::shared_ptr<Base> m_basePointer;
      
        A();
        ~A();
      };

      И Base будет коррекно разрушен в деструкторе. Единственное - деструктор должен быть явно реализован в cpp-файле, поскольку автоматически сгенерированный деструктор не скомпилируется.
      Ответить
    • Объясните дурачку из Питонии, в чём разнится мужду struct и class в плюсах?
      Ответить

    Добавить комментарий