跟我学C++中级篇—non-transient异常
一、non-transient
non-transient,非瞬时。在C++的语意范围内,一般指的是异常对象生命周期不会自动结束的情况。当然,在其它语言如Java中也有类似的机制。其实象生命周期这种名词,在以前的C++中,几乎很少听到。所以,对transient这个词也就提及的很少了。不过随着标准的不断演进,生命周期也提到的越来越频繁,这个词也就不能避开了。
二、non-transient异常和transient异常
在constexpr的求值异常时,提到了non-transient和transient异常,正是基于生命周期的前提说明的。下面对这两个名词进行一下说明:
- Transient(瞬时)异常:指在constexpr函数内部抛出并被捕获,异常对象在catch块结束时自动销毁
- Non-transient(非瞬时)异常:指异常对象试图"逃逸"出常量求值上下文,或者其生命周期扩展到常量求值之外的范围
三、例程说明
根据前面的分析说明,看一下相关的例程:
// Transient异常
constexpr void testTransient() {try {throw ownerException{}; // 内部处理} catch (ownerException) {// Catch后销毁}
}// Non-transient异常
constexpr auto testNonTransient() -> std::exception_ptr {try {throw err{};} catch (...) {return std::current_exception(); // 编译期的异常可能转移到运行时}
}
constexpr auto stored = testNonTransient(); // err:non-transient异常
代码非常简单,不再分析。
四、非瞬时异常的分析
non-transient异常,其实就是在生命周期中严格控制不同的生命周期不能进行跨转,比如编译时的异常对象不能在运行时仍然可以使用。换句话说,生命周期的控制必须有明确的界限,有一个显式的结束时间点。生命周期确定后,各种资源特别是内存的资源就可以得到安全的控制,而不会导致多数生命周期的重叠,引起的不同类型的内存处理的异常。
比如具体到constexpr,它可以保证其编译期的特性,而不用考虑在运行期的交互问题。这样对于开发者来说,也减少了相关的开发量和复杂度。可以这样理解,non-transient就是控制异常从编译时"逃逸"到运行时的安全机制。
五、总结
阅读和分析标准的相关文件,就会发现标准发展的演进过程。如果能将相关的体系在心胸中描画的清楚,则可以纲举目张的掌握C++的技术路线,从而能够可以更条理分明的安排C++的学习并应用到实际的工程项目中。