MyClass(expr); 之间的范围差异和 MyClass myObject(expr);
我有一个统计管理器,它通过测量方法执行所需的时间来检查我的应用程序性能。它的用法是这样的:
myStatManager.StartStat("Rendering");
Render();
myStatManager.StopStat("Rendering");
屏幕的输出将告诉我该方法花费了多长时间。
为了方便起见,我编写了一个虚拟对象,它在创建和销毁对象时调用这两个方法。这使我能够利用 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 Studio 2008 C++;
Edit2:啊,我现在明白了,除非我将对象绑定到变量,否则它会在表达式求值后被销毁。感谢您的帮助。
有谁知道为什么C++这么写?如果临时变量立即被销毁,它还有什么用呢?
I have a statistics manager that examines my application performance by measuring the time it takes for a method to execute. It's usage is like this:
myStatManager.StartStat("Rendering");
Render();
myStatManager.StopStat("Rendering");
The output to screen will tell me how long that method took.
For convenience, I have written a dummy object, that calls these two methods as the object is created and destroyed. This allows me to use C++ scope rules to my advantage and only type the stat tracking lines once instead of twice as above.
class ScopedStat
{
string label;
ScopedStat(string inLabel): label(inLabel) { myStatManager.StartStat(label); }
~ScopedStat() { myStatManager.StopStat(label); }
}
The expected usage is as follows:
{
ScopedStat("Rendering");
Render();
}
However, this does not work, as perhaps the compiler or something has optimized the ScopedStat object out. The reported time is a fraction of a millisecond and nowhere near the time it should take to render. My question is, why does this way not work? Does this object not get destroyed at the end of scope?
Edit: I have found a workaround:
{
ScopedStat ss("Rendering");
Render();
}
This works as intended--the object gets destroyed only at the end of the curly bracket. Though, I'd still like to know why.
Note: Using Microsoft Visual Studio 2008 C++;
Edit2: Ah, i understand now that unless i bind my object to a variable it is destroyed after the expression is evaluated. Thanks for all your help.
Does anyone know why C++ is written this way? What use is a temporary variable if it gets destroyed immediately?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您没有创建一个碰巧没有名称的普通变量。您正在创建一个临时,并且它在声明它的
完整表达式
末尾不再存在。 (也就是说,在调用Render()
之前,ScopedStat
已经出现并消失了。)您必须给它一个名称。
为了回答您的最后一个问题,当您执行以下操作时,这是非常有意义的:
只要调用
doFoo
,临时变量就存在,这是正确的。You're not creating a normal variable that just happens to have no name. You're creating a temporary, and it ceases to exist at the end of the
full-expression
in which it was declared. (That is, beforeRender()
is invoked, theScopedStat
has come and gone already.)You'll have to give it a name.
To answer your final question, this makes perfect sense when you do something like:
The temporary lives as long as does the call to
doFoo
which is just right.如果您不使用对象的标识符,它将成为临时对象,并在它所属的表达式结束后被销毁。换句话说,它具有该单个表达式的范围。
您必须为对象命名,以便它们能够生存到括号范围的末尾。
If you don't use an identifier for an object, it becomes a temporary object and gets destroyed after the expression it belongs to ends. In other words, it has the scope of that single expression.
You have to name your objects for them to live until the end of the bracket scope.
您创建了一个临时对象,该对象立即超出范围,即下一行开始执行时。以便在渲染之前完成启动和停止。
You have created a temp object which is out of scope immediately, that is when the next line starts to execute. so that start and stop are done before the render.