ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 在函数调用中访问并移动unique_ptr

2019-08-24 21:08:30  阅读:158  来源: 互联网

标签:c unique-ptr


我有一个类似于以下的部分.

struct derive : base{
    derive(unique_ptr ptr): base{func(ptr->some_data), std::move(ptr)}{}
};

从理论上讲,它应该有效.但由于编译器(vs2015)没有严格遵循标准,因此func(ptr-> some_data),std :: move(ptr)的顺序是未定义的,即ptr可以在访问之前移动.

所以我的问题是如何使这个细分市场按预期工作?

完整代码如下:

#include <memory>

struct base {
    virtual ~base() = 0 {}

protected:
    base(std::unique_ptr<base> new_state) :
        previous_state{ std::move(new_state) } {}
private:
    std::unique_ptr<base> previous_state;
};

struct derive_base : base {
    int get_a() const noexcept {
        return a;
    }
protected:
    derive_base(int const new_a, std::unique_ptr<base> new_state) :
        base{ std::move(new_state) }, a{ new_a } {}
private:
    int a;
};

struct final_state : derive_base {
    final_state(std::unique_ptr<base> new_state) :
        derive_base{ dynamic_cast<derive_base&>(*new_state).get_a(), std::move(new_state) } {}
};

解决方法:

你可以使用构造函数链来修复它:

struct derive : base
{
  private:
    derive(const D& some_data, unique_ptr<X>&& ptr) : base{some_data, std::move(ptr)} {}
  public:
    derive(unique_ptr<X> ptr): derive(func(ptr->some_data), std::move(ptr)) {}
};

原因:正如我在其他答案中所解释的那样,对func的调用肯定发生在委托构造函数调用之前,而实际移动unique_ptr(而不仅仅是更改其值类别)肯定发生在内部.

当然,这依赖于另一个C 11功能,Visual C可能会或可能没有正确.幸运的是,delegating constructors are listed as supported since VS2013.

更好的做法是始终通过引用接受std :: unique_ptr参数,如果您打算从它们中窃取,则通过右值引用接受. (如果您不会窃取内容,为什么要关心调用者具有哪种类型的智能指针?只需接受原始T *.)

如果你用过

struct base
{
    virtual ~base() = 0 {}

protected:
    base(std::unique_ptr<base>&& new_state) :
        previous_state{ std::move(new_state) } {}
private:
    std::unique_ptr<base> previous_state;
};

struct derive_base : base
{
    int get_a() const noexcept {
        return a;
    }
protected:
    derive_base(int const new_a, std::unique_ptr<base>&& new_state) :
        base{ std::move(new_state) }, a{ new_a } {}
private:
    int a;
};

struct final_state : derive_base
{
    final_state(std::unique_ptr<base>&& new_state) :
        derive_base{ dynamic_cast<derive_base&>(*new_state).get_a(), std::move(new_state) } {}
};

你不会在第一时间遇到问题,并且调用者要求完全不变(必须提供rvalue,因为unique_ptr无论如何都是不可复制的)

使其成为通用规则的基本原理如下:按值传递允许复制或移动,无论哪个在呼叫站点更优化.但是std :: unique_ptr是不可复制的,所以实际的参数必须是rvalue.

标签:c,unique-ptr
来源: https://codeday.me/bug/20190824/1711759.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有