std :: unique_ptr构造函数行为

时间:2019-09-19 14:47:51

标签: c++ smart-pointers move-semantics

首先,我知道我们应该使用std::make_unique()而不是调用std::unique_ptr构造函数,我知道为什么。

但是我在看std::unique_ptr的文档来打发时间并加深对它的了解,然后发现了following examples关于构造函数用法的信息:

// unique_ptr constructor example
#include <iostream>
#include <memory>

int main () {
  std::default_delete<int> d;
  std::unique_ptr<int> u1;
  std::unique_ptr<int> u2 (nullptr);
  std::unique_ptr<int> u3 (new int);
  std::unique_ptr<int> u4 (new int, d);
  std::unique_ptr<int> u5 (new int, std::default_delete<int>());
  std::unique_ptr<int> u6 (std::move(u5));
  std::unique_ptr<int> u7 (std::move(u6));
  std::unique_ptr<int> u8 (std::auto_ptr<int>(new int));

  std::cout << "u1: " << (u1?"not null":"null") << '\n';
  std::cout << "u2: " << (u2?"not null":"null") << '\n';
  std::cout << "u3: " << (u3?"not null":"null") << '\n';
  std::cout << "u4: " << (u4?"not null":"null") << '\n';
  std::cout << "u5: " << (u5?"not null":"null") << '\n';
  std::cout << "u6: " << (u6?"not null":"null") << '\n';
  std::cout << "u7: " << (u7?"not null":"null") << '\n';
  std::cout << "u8: " << (u8?"not null":"null") << '\n';

  return 0;
}

它生成(并且通过执行代码验证了它)以下结果:

  

u1:空
  u2:空
  u3:不为空
  u4:不为空
  u5:空
  u6:空
  u7:不为空
  u8:不为空

我正在努力理解的是:

  • 为什么u4有效而u5无效(nullptr)?
  • 为什么u7有效但u6无效?

也许这些问题是非常基本的,但是我完全不明白这一点。

如果有人能启发我解决这些问题,我将不胜感激。

3 个答案:

答案 0 :(得分:6)

std::move被命名为move是有原因的。当您从一个std::unique_ptr移到另一unique_ptr时,您从其中移出的那个将变为nullptr。别无选择,毕竟这是一个 unique ptr,两个共享相同数据的__import__("Face_recognition/detect_simple") from flask import Flask app = Flask(__name__) @app.route("/") def main(): return "OK"; @app.route('/api1') def api1(): return "OK" if __name__ == "__main__": app.run() 实例将违反此规定。 (同样,超出范围都会两次调用删除程序,然后整个地狱都变得松散了。)

答案 1 :(得分:5)

  

为什么u4有效而u5无效(nullptr)?

因为u5是在u6的初始化中移出的,而u4却没有移出。保证move构造函数将从指针移动到null。它不能指向与u6相同的对象,因为那样会违反唯一性约束。

  

为什么u7有效但u6无效?

相同原因。

答案 2 :(得分:3)

移动唯一拥有的对象意味着新所有者拥有它,而以前的所有者一无所有。
很像物理对象在现实世界中的工作方式。

没有任何内容表示所有者将其转换为空指针。

最初由u5拥有的对象已首先移至u6,然后移至u7