我有一个统计管理器,它通过测量一个方法的执行时间来检查我的应用程序的性能。它的用法如下:
myStatManager.StartStat("Rendering");
Render();
myStatManager.StopStat("Rendering");screen的输出将告诉我该方法花费了多长时间。
为方便起见,我编写了一个虚拟对象,它在创建和销毁对象时调用这两个方法。这允许我使用对我有利的C++作用域规则,并且只需输入一次统计信息跟踪行,而不是上面的两次。
class ScopedStat
{
string label;
ScopedStat(string inLabel): label(inLabel) { myStatManager.StartStat(label); }
~ScopedStat() { myStatManager.StopStat(label); }
}预期用法如下:
{
ScopedStat("Rendering");
Render();
}但是,这并不起作用,因为可能是编译器或其他什么东西优化了ScopedStat对象。报告的时间只有几分之一毫秒,与渲染所需的时间相差甚远。我的问题是,为什么这种方式不起作用?这个对象在作用域结束时不会被销毁吗?
编辑:我找到了一个解决方法:
{
ScopedStat ss("Rendering");
Render();
}这就像预期的一样--对象只在花括号的末尾被销毁。不过,我还是想知道为什么。
注意:使用Microsoft Visual Studio2008 C++;
Edit2:啊,我现在明白了,除非我将我的对象绑定到一个变量上,否则它会在表达式求值后被销毁。谢谢你的帮助。
有人知道为什么C++是这样写的吗?如果临时变量立即被销毁,那么它还有什么用呢?
发布于 2011-07-18 05:42:36
{ScopedStat(“Render”);Render();}
但是,这并不起作用,因为可能是编译器或其他什么东西优化了ScopedStat对象。报告的时间只有几分之一毫秒,与渲染所需的时间相差甚远。我的问题是,为什么这种方式不起作用?这个对象在作用域结束时不会被销毁吗?
你不会创建一个没有名字的普通变量。您正在创建一个临时的,它在声明它的full-expression的末尾不复存在。(也就是说,在调用Render()之前,ScopedStat已经来了又走了。)
你得给它起个名字。
为了回答你的最后一个问题,当你这样做时,这是非常有意义的:
doFoo(ScopedStat("Rendering"));只要对doFoo的调用是正确的,临时值就会一直存在。
发布于 2011-07-18 05:34:39
如果不为对象使用标识符,它将成为一个临时对象,并在它所属的表达式结束后被销毁。换句话说,它的作用域与单个表达式相同。
您必须为对象命名,才能使它们存活到括号范围的末尾。
ScopedStat stat("Rendering");发布于 2011-07-18 05:34:38
您已经创建了一个temp对象,该对象立即超出作用域,也就是开始执行下一行时。因此启动和停止是在渲染之前完成。
https://stackoverflow.com/questions/6726902
复制相似问题