Что представляет собой допустимое состояние для «перемещенного объекта» в C ++ 11?

Я пытался обдумать, как семантика перемещения в C ++ 11 должна работать, и у меня возникли большие проблемы с пониманием того, каким условиям должен удовлетворять перемещенный объект. Глядя наответ здесь действительно не решает мой вопрос, потому что не может понять, как применить его к объектам pimpl разумным способом, несмотря на аргументы, которыесемантика перемещения идеально подходит для прыщей.

Самая простая иллюстрация моей проблемы включает в себя идиому pimpl, например:

class Foo {
    std::unique_ptr<FooImpl> impl_;
public:
    // Inlining FooImpl's constructors for brevity's sake; otherwise it 
    // defeats the point.
    Foo() : impl_(new FooImpl()) {}

    Foo(const Foo & rhs) : impl_(new FooImpl(*rhs.impl_)) {}

    Foo(Foo && rhs) : impl_(std::move(rhs.impl_)) {}

    Foo & operator=(Foo rhs) 
    {
        std::swap(impl_, rhs.impl_);

        return *this;
    }

    void do_stuff () 
    {
        impl_->do_stuff;
    }
};

Теперь, что я могу сделать, когда я перешел изFoo? Я могу безопасно уничтожить удаленный объект и назначить его, оба из которых абсолютно необходимы. Однако, если я попытаюсьdo_stuff со мнойFooвзорвется. Прежде чем я добавил семантику перемещения для моего определенияFooкаждыйFoo удовлетворил инвариант, что он могdo_stuffи это уже не так. Похоже, что не существует большого количества хороших альтернатив, поскольку (например)Foo будет включать в себя новое динамическое распределение, которое частично отвергает цель семантики перемещения. Я мог бы проверить,impl_ вdo_stuff и инициализировать его по умолчаниюFooImpl если это так, но это добавляет (обычно ложную) проверку, и если у меня есть много методов, это будет означать, что нужно помнить, чтобы выполнить проверку в каждом из них.

Должен ли я просто отказаться от идеи, что возможностьdo_stuff является разумным инвариантом?

Ответы на вопрос(2)

Ваш ответ на вопрос