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