简体   繁体   English

C ++对象生存期优化

[英]C++ object lifetime optimizations

I'm trying to use RAII to create objects which act on a stream until they're destroyed. 我正在尝试使用RAII来创建在流上行动的对象,直到它们被破坏。 For example, I have a stream that flushes itself whenever endl is added. 例如,每当添加endl时,我都会有一个刷新自身的流。 Most of the time I want this, but not always. 大部分时间我都想要这个,但并非总是如此。 I want to be able to say "don't flush on endl" but I also need it to be exception safe. 我希望能够说“不要在endl上刷新”,但我也需要它是异常安全的。 So I can't just do stream->NoFlush() to set a class member. 所以我不能只做stream->NoFlush()来设置一个类成员。 Anyway, what I'm wanting to know is this. 无论如何,我想知道的是这个。 If I have code like 如果我有类似的代码

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.

Is the compiler allowed to optimize the lifetime of no_flush? 是否允许编译器优化no_flush的生命周期? For instance, it's not used after line 2, but I need it to stay around until the end. 例如,它在第2行之后没有使用,但我需要它一直保持到最后。 I haven't really heard of any optimizations like this, so I think I'm okay, but I'd like to make sure. 我还没有听说过这样的任何优化,所以我觉得我没事,但我想确定一下。

No, the compiler isn't allowed to optimize that away. 不,编译器不允许优化它。 The destructor will be called exactly when the object goes out of scope. 当对象超出范围时,将完全调用析构函数。

What it could do is optimize copies of it if NoFlush takes the parameter by value, but that shouldn't matter. 如果NoFlush按值获取参数,它可以做的是优化它的副本,但这无关紧要。

Copy elision is the only optimization the compiler can perform that affects observable behavior. 复制省略是编译器可以执行的唯一影响可观察行为的优化。

I'd do it like this: 我这样做:

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;
};

Now you can use it like this: 现在您可以像这样使用它:

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

    // do stuff
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM