Skip to content

[pull] master from parallel101:master #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions slides/move/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.12)

set(CMAKE_CXX_STANDARD 20)

project(main)

set(SOURCES main.cpp resource.cpp)

add_executable(main ${SOURCES})
target_compile_options(main PRIVATE -Wall -Wextra)
34 changes: 34 additions & 0 deletions slides/move/conclude.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <memory>
#include <vector>

// 掌管资源的类?四大函数全部删光!然后安心定义析构函数
struct Resource {
Resource() {
// 分配资源
}

Resource(Resource &&) = delete;
Resource(Resource const &) = delete; // 可省略不写
Resource &operator=(Resource &&) = delete; // 可省略不写
Resource &operator=(Resource const &) = delete; // 可省略不写

~Resource() {
// 释放资源
}
};

// 如果这个类需要作为参数传递,需要移动怎么办?
std::unique_ptr<Resource> p = std::make_unique<Resource>();

// 每次都要 std::move 不方便,我想要随心所欲的浅拷贝,就像 Java 对象一样,怎么办?
std::shared_ptr<Resource> q = std::make_shared<Resource>();

// 不管理资源的类?那就都不用定义了!编译器会自动生成
struct Student {
std::string name;
int age;
std::vector<int> scores;
std::shared_ptr<Resource> bigHouse;

// 编译器自动生成 Student 的拷贝构造函数为成员全部依次拷贝,不用你自己定义了
};
31 changes: 31 additions & 0 deletions slides/move/lifetest.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <cstdio>

struct C {
C() {
puts("C()");
}

C(C &&) noexcept {
puts("C(C &&)");
}

C(C const &) {
puts("C(C const &)");
}

C &operator=(C &&) noexcept {
puts("operator=(C &&)");
return *this;
}

C &operator=(C const &) {
puts("operator=(C const &)");
return *this;
}

~C() {
puts("~C()");
}
};
53 changes: 53 additions & 0 deletions slides/move/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

struct IndentGuard {
IndentGuard(std::string &indent_) : indent(indent_) {
oldIndent = indent;
indent += " ";
}

IndentGuard(IndentGuard &&) = delete;

~IndentGuard() {
puts("析构函数");
indent = oldIndent;
}

std::string oldIndent;
std::string &indent;
};

struct Codegen {
std::string code;
std::string indent;

void emit(std::string text) {
code += indent + text + "\n";
}

void emit_variable(std::string name) {
code += indent + "int " + name + ";\n";
}

void codegen() {
emit("int main() {");
{
IndentGuard guard(indent);
emit_variable("i");
emit_variable("j");
}
emit("}");
emit_variable("g");
}
};

int main() {
Codegen cg;
cg.codegen();
std::cout << cg.code;
return 0;
}
69 changes: 69 additions & 0 deletions slides/move/main_finally.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <functional>

using namespace std;

template <class Callback>
struct Finally {
Callback func;
bool valid;

Finally() : func(), valid(false) {}

Finally(Callback func) : func(func), valid(true) {
}

Finally(Finally &&that) noexcept : func(std::move(that.func)), valid(that.valid) {
that.valid = false; // 如果要支持移动语义,必须有个 bool 变量表示空状态!
}

Finally &operator=(Finally &&that) noexcept {
if (this != &that) {
if (valid) {
func();
}
func = std::move(that.func);
valid = that.valid;
that.valid = false;
}
return *this;
}

void cancel() {
valid = false;
}

void trigger() {
if (valid) {
func();
}
valid = false;
}

~Finally() {
if (valid) {
func();
}
}
};

template <class Callback> // C++17 CTAD
Finally(Callback) -> Finally<Callback>;

int main() {
Finally cb = [] {
puts("调用了 Finally 回调");
};
srand(time(NULL));
bool success = rand() % 2 == 0;
if (success) {
puts("操作失败,提前返回");
// 此处提前返回导致析构,会自动 trigger
return -1;
}
puts("操作成功");
cb.cancel(); // cancel 后,析构不再自动 trigger 了
return 0;
}
75 changes: 75 additions & 0 deletions slides/move/main_resource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <cstdio>
#include <cstdlib>
#include <memory>

using namespace std;

//struct Resource {
// void *p;
//
// Resource() {
// puts("分配资源");
// p = malloc(1);
// }
//
// Resource(Resource &&) = delete;
//
// ~Resource() {
// puts("释放资源");
// free(p);
// }
//};

struct Resource {
private:
struct Self {
void *p;

Self() {
puts("分配资源");
p = malloc(1);
}

Self(Self const &that) {
puts("复制资源");
p = malloc(1);
}

~Self() {
puts("释放资源");
free(p);
}
};

shared_ptr<Self> self;

Resource(shared_ptr<Self> self_) {
self = self_;
}

public:
Resource() {
self = make_shared<Self>();
}

Resource(Resource const &) = default;

Resource clone() const {
return make_shared<Self>(*self);
}

void speak() const {
printf("旺旺,我的资源句柄是 %p\n", self->p);
}
};

void func(Resource x) {
x.speak();
auto y = x.clone();
y.speak();
}

int main() {
auto x = Resource();
func(x);
}
9 changes: 9 additions & 0 deletions slides/move/main_respimpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "resource.hpp"

using namespace std;

int main() {
Resource res;
res.speak();
return 0;
}
31 changes: 31 additions & 0 deletions slides/move/resource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "resource.hpp"
#include <cstdio>

struct Resource::Self {
FILE *p;

Self() {
puts("打开文件");
p = fopen("CMakeCache.txt", "r");
}

Self(Self &&) = delete;

void speak() {
printf("使用文件 %p\n", p);
}

~Self() {
puts("关闭文件");
fclose(p);
}
};

Resource::Resource() : self(std::make_unique<Self>()) {
}

void Resource::speak() {
return self->speak();
}

Resource::~Resource() = default;
16 changes: 16 additions & 0 deletions slides/move/resource.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <memory>

// P-IMPL 模式
struct Resource {
private:
struct Self;

std::unique_ptr<Self> self;

public:
Resource();
void speak();
~Resource();
};
Binary file added slides/thread/Presentation3MTSafe.pptx
Binary file not shown.