内部交换子类型的范例



假设我有这个:

struct Base {
virtual void swap();
Expensive mem;
};
struct Left : Base {
void swap() override;
};
struct Right : Base {
void swap() override;
};

给定一个包含LeftRight对象的vector<shared_ptr<Base>> foo。假设元素13是Left,现在我希望它是Right。我可以做一些类似的事情:

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

但现在我们假设Expensive的构建或复制成本非常高,并且假设LeftRight不包含自己的成员,它们只是操纵和解释mem的不同方式。有没有一种方法可以让我投射或告诉元素13,它现在是一个Right,而不破坏那里的Left?我可以使用enable_shared_from_this或类似的方法来处理破坏和重建,我可以称之为foo[13].swap(),它会"变成"Right吗?

好吧,您可以考虑将LeftRight设为同一类型。但是如果你不能做到这一点,那么你仍然可以利用移动语义。假设CCD_ 17是可廉价移动的。然后你可以做这样的事情:

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处于可破坏状态,所以在我看来,这个代码将是明确定义的(。

最新更新