首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MyClass (Expr)和MyClass myObject(Expr)的作用域差异;

MyClass (Expr)和MyClass myObject(Expr)的作用域差异;
EN

Stack Overflow用户
提问于 2011-07-18 05:30:48
回答 3查看 148关注 0票数 2

我有一个统计管理器,它通过测量一个方法的执行时间来检查我的应用程序的性能。它的用法如下:

代码语言:javascript
复制
myStatManager.StartStat("Rendering");
Render();
myStatManager.StopStat("Rendering");

screen的输出将告诉我该方法花费了多长时间。

为方便起见,我编写了一个虚拟对象,它在创建和销毁对象时调用这两个方法。这允许我使用对我有利的C++作用域规则,并且只需输入一次统计信息跟踪行,而不是上面的两次。

代码语言:javascript
复制
class ScopedStat
{
    string label;
    ScopedStat(string inLabel): label(inLabel) { myStatManager.StartStat(label); }
    ~ScopedStat() { myStatManager.StopStat(label); }
}

预期用法如下:

代码语言:javascript
复制
{
    ScopedStat("Rendering");
    Render();
}

但是,这并不起作用,因为可能是编译器或其他什么东西优化了ScopedStat对象。报告的时间只有几分之一毫秒,与渲染所需的时间相差甚远。我的问题是,为什么这种方式不起作用?这个对象在作用域结束时不会被销毁吗?

编辑:我找到了一个解决方法:

代码语言:javascript
复制
{
    ScopedStat ss("Rendering");
    Render();
}

这就像预期的一样--对象只在花括号的末尾被销毁。不过,我还是想知道为什么。

注意:使用Microsoft Visual Studio2008 C++;

Edit2:啊,我现在明白了,除非我将我的对象绑定到一个变量上,否则它会在表达式求值后被销毁。谢谢你的帮助。

有人知道为什么C++是这样写的吗?如果临时变量立即被销毁,那么它还有什么用呢?

EN

回答 3

Stack Overflow用户

发布于 2011-07-18 05:42:36

{ScopedStat(“Render”);Render();}

但是,这并不起作用,因为可能是编译器或其他什么东西优化了ScopedStat对象。报告的时间只有几分之一毫秒,与渲染所需的时间相差甚远。我的问题是,为什么这种方式不起作用?这个对象在作用域结束时不会被销毁吗?

你不会创建一个没有名字的普通变量。您正在创建一个临时的,它在声明它的full-expression的末尾不复存在。(也就是说,在调用Render()之前,ScopedStat已经来了又走了。)

你得给它起个名字。

为了回答你的最后一个问题,当你这样做时,这是非常有意义的:

代码语言:javascript
复制
doFoo(ScopedStat("Rendering"));

只要对doFoo的调用是正确的,临时值就会一直存在。

票数 4
EN

Stack Overflow用户

发布于 2011-07-18 05:34:39

如果不为对象使用标识符,它将成为一个临时对象,并在它所属的表达式结束后被销毁。换句话说,它的作用域与单个表达式相同。

您必须为对象命名,才能使它们存活到括号范围的末尾。

代码语言:javascript
复制
ScopedStat stat("Rendering");
票数 3
EN

Stack Overflow用户

发布于 2011-07-18 05:34:38

您已经创建了一个temp对象,该对象立即超出作用域,也就是开始执行下一行时。因此启动和停止是在渲染之前完成。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6726902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档