簡體   English   中英

C ++如何使用破壞狀態的析構函數處理對象的副本?

[英]C++ How to handle copy of objects with destructor that damages the state?

我不確定我的措詞是否正確。

基本上,我有一個這樣的課:

class A
{
public:
    A()
    {
        CreateHandle(&m_handle);
    }

    ~A() 
    { 
        DeleteHandle(&m_handle); 
    }

private:
    Handle m_handle;
}

它是另一個類的成員:

class B
{
public:
    B(int data) : m_data(data) {} 
    /* ... */

private:
    A m_a;
    int m_data;
}

最后,我有了第三類,有點像B的容器:

class C
{
public:
    /* ... */
    void AddOneB(B b)
    {
        m_bs.push_back(b);
    }        

private:
    std::vector<B> m_bs;
}

最后,在創建C實例的代碼中,我將執行以下操作:

...
C cObj;
cObj.AddOneB( B(23) );
...

我的問題是A的析構函數實際上破壞了它在其構造函數中創建的內存。 因此,這樣做會導致我的cObj得到一個B和一個A ,這不好。

我的第一個想法是將BA實例設為std::shared_ptr ,但是我想知道是否還有其他范式(就是這個詞)來處理這種情況?

我看不到復制構造函數或移動構造函數在這里有什么幫助,因為無論如何都會調用析構函數。

您需要做出選擇: A擁有Handle 唯一所有權 ,或者它擁有它的共享所有權

如果是前者,則需要使A不可復制。 對於問題中出現的問題。 如果是C ++ 11,則應使其可移動:

A(const A&) = delete;
A& operator=(const A&) = delete;

A(A&& rhs) {
   // transfer ownership of m_handle from rhs to this
   // so that rhs doesn't destroy it
}

如果是后者,則需要引用該Handle以便僅A一個副本銷毀它:

class A {
    int* refCnt;
    Handle m_handle;

public:
    A()
    {
        CreateHandle(&m_handle);
        refCnt = new int(1);
    }

    A(const A& rhs)
    : m_handle(rhs.m_handle)
    , refCnt(rhs.refCnt)
    {
        (*refCnt)++; // now we have an additional reference
    }

    ~A() {
        if (--*refCnt == 0) {
            // only destroy if we're the LAST one
            DeleteHandle(&m_handle);
        }
    }
};

共享所有權更加昂貴(如果擔心的話,我上面寫的也不是線程安全的),因此請選擇最確定的所有權。 絕對不能擁有表示唯一所有權的可復制類型-這很麻煩。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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