2011-02-11 25 views
1

我有一種情況,有些類似於這樣:它是沒關係的對象,告訴它的主人將它刪除

class Owner { 
public: 
    enum Type {TypeB, TypeC}; 
    void swap(Type type); 
private: 
    A* m_a; 
}; 

class A { 
}; 

class B : public A { 
    void foo(); 
    Owner* m_owner; 
}; 

class C : public A { 
    void bar(); 
    Owner* m_owner; 
}; 

void Owner::swap(Type type) { 
    if (type == TypeC) { 
    delete m_a; 
    m_a = new C(); 
    } else if (type == TypeB) { 
    delete m_a; 
    m_a = new B(); 
    } 
} 

void B::foo() { 
    m_owner->swap(TypeC); 
    // will be deleted after this!! 
} 

有有一個指向基本類型A的那個對象的所有者類類型B有一個指向它的所有者的指針。有一種情況,我們希望該對象告訴其所有者將其交換爲另一種A類型:C。

B :: foo是否安全地告知其所有者刪除它?我知道如果你在調用Owner :: swap()之後做任何事情,它會崩潰。這有點像「刪除這個」場景。

+2

在調用`new C()`之前,不要調用`m_a`上的delete。這不是特例安全。如果新操作失敗,這將導致堆棧展開,並可能導致所有者的析構函數中的雙重刪除(爲了簡單起見,我假設您將其忽略)。做一個新/交換/刪除或最好使用智能指針。 – 2011-02-11 21:09:21

+1

在`Owner :: swap(Type type)`中,`delete m_b;`行應該是'delete m_a;`,因爲`Owner`中沒有成員`m_b`。 – 2011-02-11 21:16:11

+0

我修復了這個問題,thx。 – 2011-02-11 21:18:23

回答

2

如果您已將A的析構函數定義爲virtual那麼這完全沒問題。

順便問一下,你的代碼需要小的修正:

else if (type == TypeB) { 
    delete m_a; //not m_b, as Owner doesn't have any member named `m_b`. 
    m_a = new B(); 
    } 

但我不知道該對象被刪除在這裏,它調用swap功能嗎?如果是這樣,那麼我會說你的課程有一個設計問題,並且你的課程可能會在此後崩潰。

1

如果調用交換後嘗試訪問類中的字段,它會崩潰(不一定會崩潰,但會啓動內存損壞情況)。

我想說的是:

void B::foo() { 
    //this valid 
    m_owner->swap(TypeC); 
    //this invalid 
} 
1

它確定地說,只要你不再使用它的對象所有者刪除對象。對象自殺也是可以的(delete this),本標準在這種情況下不做任何道德判斷。

相關問題