※ 引述《KanoLoa (卡)》之銘言:
: 需求是這樣的:
: 1.有一 Class,是專門用來當作儲存的資料結構。
: 2.當程式運行中,要執行刪除功能時,一旦確定刪除某筆資料,
: 要保證儲存資料的那個Class其解構子功能要能馬上執行。
: ----------------------------------------------------
: 所以我的作法大概是像這樣:
: Class * A = new Class[5]; //將 A 指向有五筆CLASS的陣列
: → 假設要刪除的是 A[3] 這筆資料 ←
: Class *temp = &A[3] ; //將 temp 指向 第四筆Class
: Delete temp ;
以上的作法, 因為此五個物件 是由array new來配置, 也
應該經由 delete [] 來一起銷毀( 撇開原地建置的情形)
, 中途如果隨便去刪除某一個匿名物件, 那麼在最後 de-
lete A時將會再呼叫一次解構子, 因為沒有合適的物件存
在該位置上, 會當機也不意外了, 另外還有一種極端的例
子
struct Base { int x; };
struct Derived : public Base { int y; };
Derived *p = new Derived;
delete (static_cast<Base*>( p ) );
以上的程式碼將會造成一個物件的切割, 只刪除父類別的
子物件而保留子類別的部份, 所以有些書的作者不建議你
直接操作物件陣列. 如果父子類別物件大小不一樣, 指標
的位址計算將會算錯, 對不合法的位址嚐試呼叫其解構子
Derived *array = new Derived[ 10 ];
delete [] (static_cast<Base*>( array ) );
你可以考慮使用下面的程式碼來改善這個問題, 也可以隨
心所欲控制一個物件的出生跟死亡
typedef vector<shared_ptr<Class> > ContainerType;
ContainerType A( 5 );
// 建立物件
for( ContainerType::iterator it = A.begin();
it != A.end(); ++it )
{
it->reset( new Class );
}
// 刪除某一個物件
A[ 3 ].reset();
其實要用 pointer to pointers來作也是可以的, 不過要
很小心上面說過的情況
Class **A = new Class*[ 10 ];
// 建立物件
for( int index = 0; index != 10; ++index )
A[ index ] = new Class;
// 刪除物件
delete A[ 3 ];
不過再回來看看你的需求, 我有個疑問 :「一個物件是否
真的必需因為資源使用完畢而一定要被刪除」?因為像是
標準庫的 fstream 也可以透過 open/close來操作其他檔
案, 如果沒有特別強烈要求, 通常我會在Class 類別內加
入 create、destroy等方法來重複使用該物件.
: 如此由Class解構子中的訊息得知,那解構子的確會被執行。
: -------------------------------------------------------
: 在執行時都是正確的數據,但是一旦我多做幾次新增資料、刪除,
: 就有可能出現當機的情況:程式崩潰不動、顯現亂碼的情況。
: 是否是這樣的方式不夠洽當嚴謹呢?
: 想請問是否有比較好的方式,可以直接呼叫特定某筆CLASS的解構子,
: 最好是可以呼叫位於Class陣列中 的特定一筆。(像是指定陣列中的 A[3] )
: 感謝。
--
◢████ ◢█ ◢██◣ ◢█ ◢███ ◢█ T-ara版怎麼去
████◤ ██ ◢██◣█ ██ ████ ██ s ~> T-ara
█/███ ██ ██ ██ █/█ ◢███ █/█ 歡迎您的光臨
████◤ ██ ██ ██ ██◤ ███◤ ██◤ 恩靜、智妍、孝敏
█/███ ██ █/██◤ ██ █/██ ██ 素妍、居麗、寶藍
████◤ █◤ ◥██◤ █◤ ████◤█◤ ψmakigoto123
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.197.115
※ 編輯: loveme00835 來自: 140.121.197.115 (10/19 09:36)