簡體   English   中英

shared_ptr不報告引用的對象刪除

[英]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;
}

這將打印/保存已刪除的對象的數據成員,而不報告任何類型的錯誤。

請寫信:

  1. 為什么shared_ptr pObj不報告(在運行時)底層對象已被刪除?
  2. 由於我正在創建一個const shared_ptr,意味着不能使用它來引用任何其他對象,為什么在刪除對象時不調用lambda。
  3. 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM