我有以下问题
Buffer buffer1;
Buffer buffer2;
std::unique_ptr<const Buffer> hotBuffer;
std::unique_ptr<Buffer> backBuffer;我希望在读取热缓冲区时填充回缓冲区,并希望热缓冲区是不可写的,并为此原因使用const,但在读取和填充回缓冲区之后的某个时刻,我希望将这些缓冲区交换过来。这些缓冲区相当大,所以我不想复制它们,因此进行了unique_ptr交换。
我要做的事情是:
hotBuffer.swap(backBuffer);但无论我尝试哪种const_cast变体,似乎都无法让它发挥作用。
有解决办法吗?还是精神错乱?
发布于 2020-11-30 08:21:22
要进行交换,您需要兼容的const限定条件,因为否则指向const的指针需要转换为指向非const的指针。要获得兼容的const资格,您必须创建一个临时的强制转换,如Igor的评论所示。
所以..。就像这样:
template<typename U, typename T>
std::unique_ptr<U> const_pointer_cast(std::unique_ptr<T>&& ptr) {
return std::unique_ptr<U>(const_cast<U*>(ptr.release()));
}
void swap_buffers(std::unique_ptr<const Buffer>& hotBuffer, std::unique_ptr<Buffer>& backBuffer) {
backBuffer = const_pointer_cast<Buffer>(std::exchange(hotBuffer, std::move(backBuffer)));
}发布于 2020-12-04 06:53:54
我希望在读取热缓冲区时填充回缓冲区,并希望热缓冲区不可写,并希望基于此原因使用
const,
因此,您决定更改您的实现以强制执行所需的接口。通常,这是一个次优的方法。
最好是封装更多。我会将这些变量重新设想为一个类,其中两个缓冲区在内部都是可写的,但是外部代码将热缓冲区视为const。(如果这些变量已经在类中,请将它们重新想象为嵌套类。)这将是一个小类,有一个单一的、集中的目的-控制哪个区域的内存被认为是“热”的,哪个是“回”的。例如:
// Not sold on the name, but it will do for this demonstration
class BufferManager {
public:
// Instead of access to the smart pointers, provide direct access to the buffers.
// (Hide the detail of where these buffers live.)
const Buffer & hotBuffer() const { return *hot; }
Buffer & backBuffer() { return *back; }
// A way for external code to say it is time to swap buffers:
void flip() { hot.swap(back); }
// Placeholder constructor; modify to suit your needs:
BufferManager() : hot(std::make_unique<Buffer>()),
back(std::make_unique<Buffer>())
{}
private:
std::unique_ptr<Buffer> hot;
std::unique_ptr<Buffer> back;
};使用这种方法,两个智能指针都指向可修改的东西,因此不再存在交换它们的问题。不过,该类之外的任何内容都将热缓冲区视为const。
你可能想玩一下这些名字。(因为您需要BufferManager变量的名称,所以只需将访问器函数命名为hot和back就足够了,这当然意味着重命名私有数据成员。)接口可能需要改进。要点是添加一个抽象层,以便接口在适当的时候应用const,而不是应用实现。
注意:可能适当地将填充back缓冲区的代码合并到该类中。也许后台缓冲区和flip()都可以变成私有的。需要记住的一件关键事情是,这个类中的任何内容都不应该对读取热缓冲区感兴趣。这是为了处理外部代码。如果这样做了,这个类的用途就会转化为提供热缓冲区。
https://stackoverflow.com/questions/65067413
复制相似问题