我使用以下类在某个函数的开头自动设置等待光标,并在函数返回时重置光标。
class WaitCursorSetter
{
public:
WaitCursorSetter() {QApplication::setOverrideCursor(Qt::WaitCursor);}
virtual ~WaitCursorSetter() {QApplication::restoreOverrideCursor();}
};
我在函数开始时创建一个本地WaitCursorSetter
对象。由于等待游标在对象的析构函数中被重置,因此当函数返回并且对象超出范围时,我不必在方法中的每个return语句之前重置游标,因为析构函数被调用。
如果编译器优化了未引用的WaitCursorSetter
对象,则不起作用。我的问题是,编译器是否允许优化此对象?
答案 0 :(得分:6)
不允许编译器优化掉析构函数或初始化具有副作用的自动对象,我们可以通过转到草案标准部分3.7.3
来看到这一点:
如果具有自动存储持续时间的变量已初始化或a 具有副作用的析构函数,在结束前不得销毁 它的块,即使它也不会作为优化被消除 似乎未使用,除了类对象或其复制/移动可能 按照12.8的规定予以淘汰。
答案 1 :(得分:2)
这样做非常安全。事实上,在实践RAII时,它是一种经常使用的技术。编译器不会优化任何具有非平凡构造函数或析构函数的局部变量。查看What is a non-trivial constructor in C++。
为了避免关于未使用的局部变量的编译器警告,您可以使用 Q_UNUSED 宏。
答案 2 :(得分:0)
如果您可以观察到任何不同的情况,则不允许编译器删除该对象。
在这种情况下,构造函数/析构函数有副作用,因此编译器不会删除它们。
经常使用将效果委托给构造/销毁本地基于堆栈的对象的想法;例如:
{
Locker L(my_lock);
...
}
这样...
中的代码将在保持锁定的情况下执行,当您因任何原因离开作用域时,锁定将自动释放(只是离开块,执行{{1或者,如果在内部抛出异常。)