Парадигма внутреннего обмена дочернего типа - PullRequest
0 голосов
/ 14 ноября 2018

Допустим, у меня есть это:

struct Base {
    virtual void swap();
    Expensive mem;
};

struct Left : Base {
    void swap() override;
};

struct Right : Base {
    void swap() override;
};

Учитывая vector<shared_ptr<Base>> foo, который содержит Left и Right объекты.Допустим, элемент 13 был Left, теперь я хочу, чтобы он был Right.Я могу сделать что-то вроде:

foo[13] = make_shared<Right>();

Но теперь давайте предположим, что Expensive очень дорого создавать или копировать, и давайте предположим, что Left и Right не содержат своих собственных членов, ониэто просто другой способ манипулирования и интерпретации mem.Есть ли способ, которым я могу разыграть или сказать элементу 13, что теперь это Right, не разрушая Left, который был там?Могу ли я использовать enable_shared_from_this или подобное для манипулирования уничтожением и реконструкцией, где я мог бы позвонить foo[13].swap(), и он "стал бы" Right?

1 Ответ

0 голосов
/ 14 ноября 2018

Ну, вы могли бы рассмотреть Left и Right одного типа.Но если вы не можете этого сделать, тогда вы все равно можете воспользоваться семантикой перемещения.Предположим, что Expensive дешево перемещается.Тогда вы можете сделать что-то вроде этого:

struct Base {
    Base(Expensive mem) : mem(std::move(mem)) {}
    virtual std::shared_ptr<Base> swap() = 0;
    Expensive mem;
};
struct Left : Base {
    Left(Expensive mem) : Base(std::move(mem)) {}
    std::shared_ptr<Base> swap() override;
};
struct Right : Base {
    Right(Expensive mem) : Base(std::move(mem)) {}
    std::shared_ptr<Base> swap() override;
};
std::shared_ptr<Base> Left::swap() {
    return std::make_shared<Right>(std::move(mem));
}
std::shared_ptr<Base> Right::swap() {
    return std::make_shared<Left>(std::move(mem));
}
// ...
foo[13] = foo[13]->swap();

(Обратите внимание, что уничтожение исходного объекта, на который указывает foo[13], не происходит, пока не будет введено тело std::shared_ptr<Base>::operator=, к которому время swap() завершит работу и оставит mem в разрушаемом состоянии, поэтому мне кажется, что этот код будет четко определен).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...