- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 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";
}
HighVoltageCock 02.08.2018 01:37 # 0
OlegUP 02.08.2018 10:27 # +1
> 3) Создает новый объект std::thread и связывает его с потоком выполнения. Первый конструктор копирует все аргументы args... в локальную память потока, как функция:
Ты передаешь туда shared_ptr, который конструктор thread копирует.
А shared_ptr удаляет указываемый объект, когда на него больше нету ссылок.
https://ru.cppreference.com/w/cpp/memory/shared_ptr
OlegUP 02.08.2018 10:34 # 0
Но твой объект Base будет удален, как только деструтурируются все 3 этих объекта.
guest8 02.08.2018 11:59 # −999
OlegUP 02.08.2018 13:40 # 0
А именно сбрасывать use_count на значение меньшее на единицу. Как это происходит при завершении потоков.
Почему же use_count после вызова reset устанавливается в 0 -- непонятно.
Steve_Brown 02.08.2018 14:12 # +2
После reset() указатель обнулился, use_count() уже относится не к созданному когда-то экземпляру, а как бы к нулевому указателю. Это ж не release() (которого, естественно, нет).
OlegUP 02.08.2018 14:25 # 0
guest8 02.08.2018 14:40 # −999
Steve_Brown 02.08.2018 14:19 # +1
Но это тоже понятно. На самом деле мы можем вообще написать
И Base будет коррекно разрушен в деструкторе. Единственное - деструктор должен быть явно реализован в cpp-файле, поскольку автоматически сгенерированный деструктор не скомпилируется.
666_N33D135 03.08.2018 17:13 # 0
vistefan 03.08.2018 17:24 # 0
defecate-plusplus 03.08.2018 17:25 # 0
guest8 03.08.2018 17:27 # −999
guest8 03.08.2018 17:25 # −999
vistefan 03.08.2018 17:26 # 0
HighVoltageCock 03.08.2018 17:32 # 0
Если что, его сервера работают под управлением "Windows".
roskomgovno 03.08.2018 17:36 # −1
HighVoltageCock 03.08.2018 17:46 # 0
guest8 03.08.2018 17:58 # −999
roskomgovno 03.08.2018 17:59 # −1
Он действительно долго очень писал на asp classic (язык VBS), но потом перешел на ASP.NET и C#
roskomgovno 03.08.2018 18:05 # −1
Microsoft ASP.NET MVC
SQL Server 2008
C#
Visual Studio 2008 Team Suite
HighVoltageDick 04.08.2018 23:04 # 0
Факт.