Парадигма внутреннего обмена дочернего типа

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

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?

0

Решение

Ну, вы могли бы рассмотреть возможность 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 в разрушаемом состоянии, поэтому мне кажется, что этот код будет четко определен).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]