Zombie objects after std::move

I'm confused about the state of an object after it's been moved using C++0x move semantics. My understanding is that once an object has been moved, it's still a valid object, but its internal state has been altered so that when its destructor is called, no resources are deallocated.

But if my understanding is correct, the destructor of a moved object should still be called.

But, that doesn't happen when I perform a simple test:

struct Foo
{
    Foo()  
    {
        s = new char[100]; 
        cout << "Constructor called!" << endl;  
    }

    Foo(Foo&& f) 
    {
        s = f.s;
        f.s = 0;
    }

    ~Foo() 
    { 
        cout << "Destructor called!" << endl;   
        delete[] s; // okay if s is NULL
    }

    void dosomething() { cout << "Doing something..." << endl; }

    char* s;
};

void work(Foo&& f2)
{
    f2.dosomething();
}

int main()
{
    Foo f1;
    work(std::move(f1));
}

This output:

Constructor called!
Doing something...
Destructor called!

Notice the destructor is only called once. This shows that my understanding here is off. Why wasn't the destructor called twice? Here's my interpretation of what should have happened:

  1. Foo f1 is constructed.
  2. Foo f1 is passed to work, which принимает rvalue f2 .
  3. Конструктор перемещения Foo вызывается, перемещая все ресурсы в f1 на f2 .
  4. Теперь вызывается деструктор f2 , освобождение всех ресурсов.
  5. Теперь вызывается деструктор f1 , который на самом деле ничего не делает так как все ресурсы были переданы к f2 . Тем не менее, деструктор тем не менее вызывается.

Но поскольку вызывается только один деструктор, ни шаг 4, ни шаг 5 не происходит. Я провел обратную трассировку от деструктора, чтобы увидеть, откуда он был вызван, и он вызывается с шага 5. Так почему же не вызывается деструктор f2 ?

EDIT: Хорошо, я изменил это, так что он фактически управляет ресурсом. (Буфер внутренней памяти.) Тем не менее, я получаю то же самое поведение, когда деструктор вызывается только один раз.

10
задан bitek 15 March 2013 в 13:15
поделиться