Re: [問題] 建構解構的基本問題

作者: CoNsTaR ((const *))   2016-04-30 12:03:25
※ 引述《dreamboat66 (小嫩)》之銘言:
: https://ideone.com/9ufeMX
: 請問上述的程式碼
: 我不確定1和2 真正被push到stack上
: bar和foo誰先被push(我觀念上1和2都是 foo先 再來是bar)
: 而我從印出this似乎1,2兩個push到stack的順序也是一樣(但不知道為啥最佳化後 stac
k
: address是小到大)
: =============以上 不知道結論有沒有錯============
: 但以我的觀念, 我是覺得先被push就是最後被解構
: 但用stack的觀念上我無法解釋 為什麼解構順序會有差別?
: 如果從code來看, 確實是很合理 但不知道為什麼stack就說不通?
: 中間有什麼盲點我搞錯了? 或是因為一些手段 導致我光看this的位址是不準確的?
: 謝謝
C++ 不論是什麼變數,建構 & 解構的順序相反
為什麼這樣規定?
假設有一個 Logger 物件和一個 Display 物件
當 Display 遇到錯誤的時候就會通知 Logger
所以 Display 存在的時候,Logger 也必須存在
因此 Display 和 Log 的建立順序應該是這樣:
Logger logger;
Display monitor;
這樣我們會合理的預期當 monitor 遇到錯誤的時候,一定可以通知 Logger
因為就算 Display 是在建構的過程中遇到錯誤,Logger 也早建構完成在那邊等了
可是,這裡有一個容易被忽略的問題,那就是解構順序
要是解構順序和建構順序相同的話,那意味著 Logger 將比 Display 更早被解構
要是真的這樣,那麼當 Display 在解構的過程中遭遇了錯誤,就會對
已經被解構的 Logger 操作,這就是所謂的 Dead Reference 造成的問題
竟然對一個已經解構的物件進行操作!!!
這樣的結果是未定義的
C++ 的設計當然不會讓這種事情發生,至少是不可能發生在 auto 變數身上
從上面這個例子可以看出因此『建構和解構順序相反』的原因
因為這樣才符合我們預期的「先宣告的變數生命周期較長」的假設
再來我們來看看 global 變數
global 變數也遵守著先建構後解構的規則 (事實上除了 new 出來的空間都遵守這個規則
)
但是,這並不代表 global 變數和 auto 變數一樣可以利用這個機制解決這類的問題
問題就出在我們無法確定 global 變數的建構時間
我們知道 global 變數的初始化是在程式 loadding 的時候,因此不存在先後的問題
因此也無法保障解構順序
再來,剛剛的初始化機制只能用在可以成為 compile time constant 的型態身上
意思就是你的 class 必須要是像 C struct 那樣的 POD 才有可能適用這樣的初始化機制
其他無法成為 compile time constant 的型別,編譯器會自動 inline 一些程式碼幫助
這些 global 變數在程式開始的時候被初始化
這代表了你也無法單純透過宣告順序來決定 globals 的建構順序,當然更不可能得知解
構順序
再來是 static 變數
static 變數分兩種,種是 local static 變數,另一種是 global static 變數
global static 在這裡就不談了,它相當於 unnamed namespace 裡的 global 變數
我們關心的是 local static 變數
要是 local static 的型別能夠成為 compile time constant 則比照 global 辦理
要是不行的話,就會在第一次用到它的時候被初始化
因此某種程度上,這種 local static 變數的解構時間是能夠被預期的(只要程式流程能
夠被預期)
我們需要解決的課題是,該如何控制這些 global 和 static 的生命週期呢?
在 MCD 裡面有一章是 singleton pattern 的實作範例
裡面就對這類的問題提出了一些解決方案
在這裡就不贅述,有興趣的話可以去查查 phoneix singleton 和 std::atexit()
或是直接拿 MCD 來翻翻會是更好的選擇啦 XD
作者: dreamboat66 (小嫩)   2016-04-30 12:52:00
可是以我的例子 bar and foo 都是auto var, 為啥解構順序 會不一樣 難道在stack上 順序不一樣嗎?
作者: CoNsTaR ((const *))   2016-04-30 13:02:00
改了一下文章內容 把我覺得比較模糊的地方拿掉了
作者: dreamboat66 (小嫩)   2016-04-30 13:33:00
但是以log看 建構感覺順序一樣 請問怎麼看出不一樣的?
作者: james732 (好人超)   2016-04-30 19:09:00

Links booklink

Contact Us: admin [ a t ] ucptt.com