Frozen5293's blog Frozen5293's blog
首页
  • 游戏开发
  • 博客相关
  • 技术问题
  • 分类
  • 标签
  • 归档
  • 友情链接
关于
GitHub (opens new window)

Frozen5293

刀剑钺戟摧狂浪,山河草木岁众生
首页
  • 游戏开发
  • 博客相关
  • 技术问题
  • 分类
  • 标签
  • 归档
  • 友情链接
关于
GitHub (opens new window)
  • C++智能指针

frozen5293
2023-08-19
随笔
目录

C++智能指针


#include #include #include #include #include #include #include

# Unique 指针,Move操作

// 智能指针
struct B {
  virtual void bar() { std::cout << "B::bar\n"; }
  virtual ~B() = default;
};
struct D : B
{
    D() { std::cout << "D::D\n";  }
    ~D() { std::cout << "D::~D\n";  }
    void bar() override { std::cout << "D::bar\n";  }
};
 
// 消费 unique_ptr 的函数能以值或以右值引用接收它
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
    p->bar();
    return p;
}
 
void close_file(std::FILE* fp) { std::fclose(fp); }
 
int main()
{
   /// unique 指针存在所有权问题
  std::cout << "unique ownership semantics demo\n";
  {
      auto p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr
      /// 这里采用移动操作,使得p不在享有这个地址,或者说值的所有权交给了q
      auto q = pass_through(std::move(p)); 
      assert(!p); // 现在 p 不占有任何内容并保有空指针
      q->bar();   // 而 q 占有 D 对象
  } // ~D 调用于此
 
 
  std::cout << "Runtime polymorphism demo\n";
  {
    std::unique_ptr<B> p = std::make_unique<D>(); // p 是占有 D 的 unique_ptr
                                                  // 作为指向基类的指针
    /// 可以解引用 调用操作,和指针一样
    p->bar(); // 虚派发
   /// unique 可以存在容器里
    std::vector<std::unique_ptr<B>> v;  // unique_ptr 能存储于容器
    v.push_back(std::make_unique<D>());
    v.push_back(std::move(p));
    // emplace_back 调用构造函数的push_back
    v.emplace_back(new D);
    for(auto& p: v) p->bar(); // 虚派发
  } // ~D called 3 times
 
  std::cout << "Custom deleter demo\n";
  std::ofstream("demo.txt") << 'x'; // 准备要读的文件
  {
      std::unique_ptr<std::FILE, void (*)(std::FILE*) > fp(std::fopen("demo.txt", "r"),
                                                           close_file);
      if(fp) // fopen 可以打开失败;该情况下 fp 保有空指针
        std::cout << (char)std::fgetc(fp.get()) << '\n';
  } // fclose() 调用于此,但仅若 FILE* 不是空指针
    // (即 fopen 成功)
 
  std::cout << "Custom lambda-expression deleter demo\n";
  {
    std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr)
        {
            std::cout << "destroying from a custom deleter...\n";
            delete ptr;
        });  // p 占有 D
    p->bar();
  } // 调用上述 lambda 并销毁 D
 
  std::cout << "Array form of unique_ptr demo\n";
  {
      std::unique_ptr<D[]> p{new D[3]};
  } // 调用 ~D 3 次
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
编辑 (opens new window)
上次更新: 2024/04/16, 00:35:21
最近更新
01
Rust序列化函数
04-29
02
Rust错误处理
04-29
03
1
04-29
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Frozen5293 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式