如果 shared_ptr 被銷毀,如果在 lambda 中捕獲要在執行緒上運行,“this”會發生什么?在以下情況下,它不應該拋出例外,因為物件 Test 在執行緒完成運行之前已被銷毀。
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
using namespace std::this_thread; // sleep_for, sleep_until
using namespace std::chrono; // nanoseconds, system_clock, seconds
class Test
{
private:
int testInt = 0;
public:
std::thread TestMethod()
{
auto functor =
[this]() ->void
{
sleep_until(system_clock::now() seconds(1));
testInt; cout<<testInt<<endl;
};
std::thread t1(functor);
testInt = 6;
return t1;
}
~Test()
{
cout<<"Destroyed\n";
testInt = 2;
}
};
int main()
{
cout<<"Create Test\n";
auto testPtr = std::make_shared<Test>();
auto t = testPtr->TestMethod();
testPtr = nullptr;
cout<<"Destroy Test\n";
t.join();
return 0;
}
輸出是
Create Test
Destroyed
Destroy Test
3
lambda 如何訪問已銷毀物件的 testInt ?
uj5u.com熱心網友回復:
實際上,執行程式的硬體對物件、成員變數、參考或指標一無所知。C 源代碼中的變數變成了可執行檔案中的虛擬記憶體位置,參考或指標變成了虛擬記憶體地址。當一個物件被你的程式“破壞”時,這對機器來說毫無意義。程式只是停止為此目的使用那部分虛擬記憶體,如果程式繼續運行,它很可能很快就會為其他目的重新分配該記憶體。
如果您的程式保留了一個指向以前“銷毀”的物件的懸空參考/指標,那么通過該指標/參考的任何訪問都將是對現在未使用的記憶體位置的訪問,或者現在是某個完全不同物件的一部分來自之前的那個。這通常會導致程式的錯誤行為(也稱為“錯誤”),而這些行為尤其難以診斷。
自從物件 Test 被銷毀后,它不應該在下面的情況下拋出例外嗎?
要求每個程式都檢測懸空參考或指標的使用將對大多數程式的性能產生巨大的不利影響。要通過參考獲取某個變數的值,在大多數 CPU 架構上,可能是一條機器指令。檢測參考是否有效可能需要程式執行數十或數百條指令。
語言標準認為使用懸空參考或指標是未定義的行為。這是他們的說法,您不應該這樣做,但是您有責任確保您的程式不這樣做。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382694.html
