首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当一个是const时如何交换智能指针

当一个是const时如何交换智能指针
EN

Stack Overflow用户
提问于 2020-11-30 02:32:22
回答 2查看 131关注 0票数 0

我有以下问题

代码语言:javascript
复制
Buffer buffer1;
Buffer buffer2;

std::unique_ptr<const Buffer> hotBuffer;
std::unique_ptr<Buffer> backBuffer;

我希望在读取热缓冲区时填充回缓冲区,并希望热缓冲区是不可写的,并为此原因使用const,但在读取和填充回缓冲区之后的某个时刻,我希望将这些缓冲区交换过来。这些缓冲区相当大,所以我不想复制它们,因此进行了unique_ptr交换。

我要做的事情是:

代码语言:javascript
复制
hotBuffer.swap(backBuffer);

但无论我尝试哪种const_cast变体,似乎都无法让它发挥作用。

有解决办法吗?还是精神错乱?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-30 08:21:22

要进行交换,您需要兼容的const限定条件,因为否则指向const的指针需要转换为指向非const的指针。要获得兼容的const资格,您必须创建一个临时的强制转换,如Igor的评论所示。

所以..。就像这样:

代码语言:javascript
复制
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)));
}
票数 2
EN

Stack Overflow用户

发布于 2020-12-04 06:53:54

我希望在读取热缓冲区时填充回缓冲区,并希望热缓冲区不可写,并希望基于此原因使用const

因此,您决定更改您的实现以强制执行所需的接口。通常,这是一个次优的方法。

最好是封装更多。我会将这些变量重新设想为一个类,其中两个缓冲区在内部都是可写的,但是外部代码将热缓冲区视为const。(如果这些变量已经在类中,请将它们重新想象为嵌套类。)这将是一个小类,有一个单一的、集中的目的-控制哪个区域的内存被认为是“热”的,哪个是“回”的。例如:

代码语言:javascript
复制
// 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变量的名称,所以只需将访问器函数命名为hotback就足够了,这当然意味着重命名私有数据成员。)接口可能需要改进。要点是添加一个抽象层,以便接口在适当的时候应用const,而不是应用实现。

注意:可能适当地将填充back缓冲区的代码合并到该类中。也许后台缓冲区和flip()都可以变成私有的。需要记住的一件关键事情是,这个类中的任何内容都不应该对读取热缓冲区感兴趣。这是为了处理外部代码。如果这样做了,这个类的用途就会转化为提供热缓冲区。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65067413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档