【问题标题】:C++ object lifetime optimizationsC++ 对象生命周期优化
【发布时间】:2012-11-29 01:42:23
【问题描述】:

我正在尝试使用 RAII 创建对象,这些对象作用于流直到它们被销毁。例如,我有一个流,每当添加 endl 时它就会自行刷新。大多数时候我想要这个,但并非总是如此。我希望能够说“不要在 endl 上刷新”,但我也需要它是异常安全的。所以我不能只做stream->NoFlush() 来设置一个班级成员。无论如何,我想知道的是这个。如果我有类似的代码

CStreamModifier no_flush;
stream->NoFlush(no_flush);
// as long as no_flush is in scope I get the behaviour I want

... do some stuff on the stream, without referencing no_flush ...

// no_flush goes out of scope here.

是否允许编译器优化 no_flush 的生命周期?例如,它在第 2 行之后没有使用,但我需要它一直保留到最后。我还没有真正听说过这样的优化,所以我认为我还可以,但我想确定一下。

【问题讨论】:

    标签: c++ compiler-optimization


    【解决方案1】:

    不,编译器不允许优化它。当对象超出范围时,将准确调用析构函数。

    如果NoFlush 按值获取参数,它可以做的是优化它的副本,但这不重要。

    复制省略是编译器可以执行的唯一影响可观察行为的优化。

    【讨论】:

      【解决方案2】:

      我会这样做:

      struct Stream
      {
          bool flush = true;
          // ...
      };
      
      struct NoFlush
      {
          explicit NoFlush(Stream & s)
          : stream(s)
          , prev(stream.flush)
          { stream.flush = false; }
      
          ~NoFlush()
          { stream.flush = prev; }
      
          Stream & stream;
          bool prev;
      };
      

      现在你可以像这样使用它了:

      void foo(T arg, S brg, Stream & stream)
      {
          NoFlush _(stream);
      
          // do stuff
      }
      

      【讨论】:

      • 我从来没有遇到过你如何初始化它的语法,NoFlush(stream) 给出编译错误但NoFlush _(stream) 没有,你能解释一下区别吗?
      • @user1520427: _ 只是一个普通的名字。如果您愿意,也可以说NoFlush dennis(stream);
      猜你喜欢
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      相关资源
      最近更新 更多