Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++11 std::unique\u ptr::在移动unique\u ptr后返回的值是否有效?_C++11_Move_Unique Ptr - Fatal编程技术网

C++11 std::unique\u ptr::在移动unique\u ptr后返回的值是否有效?

C++11 std::unique\u ptr::在移动unique\u ptr后返回的值是否有效?,c++11,move,unique-ptr,C++11,Move,Unique Ptr,考虑以下代码段: class Owner { public: Owner(std::unique_ptr<int> ptr) : owned_pointer<int>(std:move(ptr)) {} private: std::unique_ptr<int> owned_pointer; }; std::unique_ptr<int> ptr(new int); int* ptr1 = ptr.get(); Owner new_owne

考虑以下代码段:

class Owner {
public:
 Owner(std::unique_ptr<int> ptr) : owned_pointer<int>(std:move(ptr)) {}
private:
 std::unique_ptr<int> owned_pointer;
};


std::unique_ptr<int> ptr(new int);
int* ptr1 = ptr.get();
Owner new_owner(std::move(ptr));
类所有者{
公众:
所有者(std::unique_ptr ptr):拥有的_指针(std:move(ptr)){}
私人:
std::唯一的\u ptr拥有的\u指针;
};
std::唯一的ptr ptr(新int);
int*ptr1=ptr.get();
所有者-新所有者(标准::移动(ptr));
只要新的所有者在范围内,就可以安全地假定ptr1有效吗?这似乎是可行的,但我找不到一个明确说明的规范-它是未定义的行为/实现特定的并且恰好对我有效,还是上面发布的代码是有效的(ptr1保证只要它保持活动状态就指向移动的指针)?

是的,它是有效的

可以有多个(普通)指针指向同一对象。问题是这些指针的有效期有多长,或者指向的对象何时被删除

一个
unique\u ptr
存储了一个普通指针并拥有所有权,这意味着它要对对象何时被销毁负责。将其移动到另一个
unique\u ptr
仅转移所有权,对象本身仍然是相同的,所有指向它的普通指针仍然有效


只有当所有权未转移(或释放)且拥有的
unique\u ptr
被销毁时,它也会销毁对象。此时,所有指向对象的普通指针都将变成悬空指针,取消对它们的引用将是非法的。

是,C++11规范保证将对象的所有权从一个
unique\u ptr
转移到另一个
unique\u ptr
不会改变对象本身的位置,并且
get()第二个
unique\u ptr
上的
返回与传输前第一个
unique\u ptr上相同的值

查看N3337,第20.7.1节:

  • 此外,
    u
    可以根据请求将所有权转移到另一个唯一指针
    u2
    。完成此类转让后,应: 后条件:

    • u2.p
      等于传输前的
      u.p
    • u.p
      等于
      nullptr
      ,并且
    • 如果预传输
      u.d
      保持状态,则该状态已传输到
      u2.d
  • 其中
    u
    是存储指针
    u.p
    唯一\u ptr
    对象


    第一个项目符号直接回答了这个问题,因为
    get()
    被指定为返回
    u.p

    unique\u ptr
    存储类型为
    int*
    的值。销毁时,它调用
    delete
    (通过traits类)
    ptr.get()
    返回
    int*
    的副本
    new\u owner
    将该
    int*
    的所有权转移,因此旧的
    unique\u ptr
    不会
    删除它,而新的将删除它。不应该有什么神奇的事情发生。除非您正在寻找standardese茶叶读物,并且对标准中可能存在的漏洞/错误感兴趣?@Yakk,是的,我正在寻找更多的标准规范或相关stl文档-我了解它是按照您描述的方式实现的,因此它是有效的。但是我想防止下一个gcc版本以不同方式实现unique_ptr并破坏发布的代码的可能性-标准是否保证这始终有效?老实说,我很清楚,如果标准与实现不一致,那么标准就是错误的(wrt
    int*
    的生存期)。这不像是关于vector的生命周期问题的迭代器抽象,实际行为和标准定义的行为可能会有所不同,也可能会有所不同。因此,任何不一致的标准茶叶阅读都只意味着标准中存在缺陷。我想,如果没有注意到标准中的此类缺陷,可能会导致gcc在f中实现该缺陷未来迭代?那么,标准真的保证了这一点吗?或者大多数实现都会显示这种行为只是巧合吗?@Knitschi明确提出了这样一个问题:“它是未定义的行为/实现特定的,并且恰好适合我,还是上面发布的代码是有效的?”我的回答是“是的,它是有效的。”-即使在任何地方都没有明确说明,但标准保证了
    unique_ptr
    的某些行为以及普通指针并将其结合起来,我认为上述保证是有效的。因此,我想知道您是否确定,因为您阅读了标准(我不想;-))它明确指出get()返回的地址在移动过程中不会改变,或者仅仅因为您认为不太可能实现在移动过程中改变地址的唯一_ptr?@Knitschi“更改地址”在这种情况下没有意义。对象有一个地址,
    unique\u ptr
    不会移动对象,它只移动其内容,即指针。如果您有相同的指针,则该指针是
    unique\u ptr
    所具有的指针的副本。无论
    unique\u ptr
    用它自己的指针做什么,都不会影响你的指针-它也不会影响对象,除非管理对象生命周期(而不是位置)的
    unique\u ptr
    销毁对象。好吧,好吧,让我们不再争论这个问题。我接受托管指针保持不变。从现在起,我的客机航空电子系统软件将依赖于此,如果飞机坠毁,我将向您转发所有电子邮件;-)