[英]shared_ptr not reporting referenced object deletion
我在MS Visual Studio 10中運行此代碼,
#include <iostream>
#include <memory>
using namespace std;
class A
{
int i;
public:
A(int j) : i(j) {}
~A() {}
void fun()
{
cout << "A::i = " << i << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A aObj(12);
std::shared_ptr<A> const pObj (&aObj,
[] (A* pA) {
cout << "lambda deleter" << endl;
});
aObj.~A();
pObj->fun();
return 0;
}
這將打印/保存已刪除的對象的數據成員,而不報告任何類型的錯誤。
請寫信:
shared_ptr
pObj不報告(在運行時)底層對象已被刪除? weak_ptr
可以在類似的情況下有所幫助。 weak_ptr
與語義一起使用,即對象引用的生命周期超過它引用的對象。 為什么shared_ptr pObj不報告(在運行時)底層對象已被刪除?
因為shared_ptr
不是魔術 1 。 它知道何時刪除包含的對象只有在刪除該對象時 。 使用shared_ptr
,您已與shared_ptr
簽訂了合同。 該合同的租戶之一(實際上,您使用任何類型的智能指針進入的任何合同)是您無法刪除指針。 該shared_ptr
實例擁有指針,就將它刪除,而不是你。
違反該合同會導致未定義的行為。
由於我正在創建一個const shared_ptr,意味着不能使用它來引用任何其他對象,為什么在刪除對象時不調用lambda。
同樣, shared_ptr
可以只知道當它刪除它包含的對象被刪除。 如果你違反合同,它對物體的狀態一無所知。
weak_ptr可以在類似的情況下有所幫助。 weak_ptr與語義一起使用,即對象引用的生命周期超過它引用的對象。
weak_ptr
並不比shared_ptr
更神奇。 weak_ptr
只知道創建它所知道的shared_ptr
集。 如果shared_ptr
不知道該對象已被刪除,則weak_ptr
也不會。
1 “魔術”,我的意思是做一些在C ++中無法做到的事情。 如果你想知道一個函數被調用(析構函數是一個函數調用),那么只有兩種方法可以做到。 該函數告訴你它已被調用(通過設置你可以看到的值),或者你設置一個系統,人們調用你的函數然后調用另一個函數。
第一個系統需要一個明確寫入的函數,讓人們知道它已被調用。 你不能用任何舊功能做到這一點; 它必須為此而設計。 第二個系統要求每個人都使用你的新功能而沒有人使用舊功能。 如果有人直接使用舊代碼,您的代碼將不會知道它。
第一種方法稱為“侵入式”(因為它要求您以特殊方式編寫對象),使用它的智能指針稱為“侵入式智能指針”。 第二種方法是非侵入式的(不需要對象的特殊代碼)。 shared_ptr
和所有當前標准的智能指針都是非侵入式的。 這意味着您可以將它們與任何對象一起使用,但只有遵守合同才能使用它們。
C ++沒有提供第三種方式。 因此,一個可以以某種方式介入析構函數調用的類,一個可以知道它的類已被調用,而沒有析構函數明確告訴它已經存在,這是不可能的。 因此將是魔術。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.