From d6b323e48a2f1568f0bdd709ce288b435dff02b9 Mon Sep 17 00:00:00 2001 From: albert12345 <1528760260@qq.com> Date: Sat, 19 Jul 2025 20:34:32 +0800 Subject: [PATCH 01/17] Modify content in learning-cxx --- exercises/00_hello_world/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/00_hello_world/main.cpp b/exercises/00_hello_world/main.cpp index 8866f3c15..fa454e132 100644 --- a/exercises/00_hello_world/main.cpp +++ b/exercises/00_hello_world/main.cpp @@ -6,6 +6,6 @@ int main(int argc, char **argv) { // TODO: 在控制台输出 "Hello, InfiniTensor!" 并换行 - std::cout : "Hello, InfiniTensor!" + std::endl; + std::cout << "Hello, InfiniTensor!" << std::endl; return 0; } From 088e9199d9dcb76e02db1521013a27aa67f064cd Mon Sep 17 00:00:00 2001 From: albert12345 <1528760260@qq.com> Date: Sun, 20 Jul 2025 00:19:38 +0800 Subject: [PATCH 02/17] Update all changes in submodule learning-cxx-02 --- exercises/01_variable&add/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/01_variable&add/main.cpp b/exercises/01_variable&add/main.cpp index 5014863fd..5d73fa231 100644 --- a/exercises/01_variable&add/main.cpp +++ b/exercises/01_variable&add/main.cpp @@ -5,6 +5,7 @@ int main(int argc, char **argv) { // TODO: 补全变量定义并打印加法运算 // x ? + int x=3; std::cout << x << " + " << x << " = " << x + x << std::endl; return 0; } From 9961a6bfecb6ab77a680b02bc4ee9ebe201b6d31 Mon Sep 17 00:00:00 2001 From: albert12345 <1528760260@qq.com> Date: Sun, 20 Jul 2025 00:46:59 +0800 Subject: [PATCH 03/17] Update all changes in submodule learning-cxx --- exercises/02_function/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/02_function/main.cpp b/exercises/02_function/main.cpp index b5eef7f28..787872882 100644 --- a/exercises/02_function/main.cpp +++ b/exercises/02_function/main.cpp @@ -16,4 +16,5 @@ int main(int argc, char **argv) { int add(int a, int b) { // TODO: 补全函数定义,但不要移动代码行 + return a+b; } From 9d336b6b94dc2e47e19d0a315a63d0eb1a076a24 Mon Sep 17 00:00:00 2001 From: albert12345 <1528760260@qq.com> Date: Mon, 21 Jul 2025 13:35:33 +0800 Subject: [PATCH 04/17] Update all changes in submodule learning-cxx --- exercises/02_function/main.cpp | 3 ++- exercises/03_argument¶meter/main.cpp | 8 ++++---- exercises/04_static/main.cpp | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/exercises/02_function/main.cpp b/exercises/02_function/main.cpp index 787872882..be4dcefa3 100644 --- a/exercises/02_function/main.cpp +++ b/exercises/02_function/main.cpp @@ -5,6 +5,7 @@ // NOTICE: 补充由内而外读法的机翻解释 // TODO: 在这里声明函数 +int add(int a, int b); int main(int argc, char **argv) { ASSERT(add(123, 456) == 123 + 456, "add(123, 456) should be 123 + 456"); @@ -16,5 +17,5 @@ int main(int argc, char **argv) { int add(int a, int b) { // TODO: 补全函数定义,但不要移动代码行 - return a+b; + return a + b; } diff --git a/exercises/03_argument¶meter/main.cpp b/exercises/03_argument¶meter/main.cpp index 7fb5d3c2f..0ff2e2d54 100644 --- a/exercises/03_argument¶meter/main.cpp +++ b/exercises/03_argument¶meter/main.cpp @@ -8,19 +8,19 @@ void func(int); // TODO: 为下列 ASSERT 填写正确的值 int main(int argc, char **argv) { auto arg = 99; - ASSERT(arg == ?, "arg should be ?"); + ASSERT(arg == 99, "arg should be 99"); std::cout << "befor func call: " << arg << std::endl; func(arg); - ASSERT(arg == ?, "arg should be ?"); + ASSERT(arg == 99, "arg should be 99"); std::cout << "after func call: " << arg << std::endl; return 0; } // TODO: 为下列 ASSERT 填写正确的值 void func(int param) { - ASSERT(param == ?, "param should be ?"); + ASSERT(param == 99, "param should be 99"); std::cout << "befor add: " << param << std::endl; param += 1; - ASSERT(param == ?, "param should be ?"); + ASSERT(param == 100, "param should be 100"); std::cout << "after add: " << param << std::endl; } diff --git a/exercises/04_static/main.cpp b/exercises/04_static/main.cpp index f107762fa..64f417694 100644 --- a/exercises/04_static/main.cpp +++ b/exercises/04_static/main.cpp @@ -10,10 +10,10 @@ static int func(int param) { int main(int argc, char **argv) { // TODO: 将下列 `?` 替换为正确的数字 - ASSERT(func(5) == ?, "static variable value incorrect"); - ASSERT(func(4) == ?, "static variable value incorrect"); - ASSERT(func(3) == ?, "static variable value incorrect"); - ASSERT(func(2) == ?, "static variable value incorrect"); - ASSERT(func(1) == ?, "static variable value incorrect"); + ASSERT(func(5) == 5, "static variable value incorrect"); + ASSERT(func(4) == 6, "static variable value incorrect"); + ASSERT(func(3) == 7, "static variable value incorrect"); + ASSERT(func(2) == 8, "static variable value incorrect"); + ASSERT(func(1) == 9, "static variable value incorrect"); return 0; } From 1dee83dbf21597a11ddb9ab394635f51ef074afc Mon Sep 17 00:00:00 2001 From: albert12345 <1528760260@qq.com> Date: Mon, 21 Jul 2025 15:23:34 +0800 Subject: [PATCH 05/17] Update 05 in submodule learning-cxx --- exercises/05_constexpr/main.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/exercises/05_constexpr/main.cpp b/exercises/05_constexpr/main.cpp index d1db6c9d8..d42c5b3ee 100644 --- a/exercises/05_constexpr/main.cpp +++ b/exercises/05_constexpr/main.cpp @@ -11,6 +11,17 @@ constexpr unsigned long long fibonacci(int i) { } } +// constexpr unsigned long long fibonacci(int n) { +// if (n <= 1) return n; +// unsigned long long a = 0, b = 1; +// for (int i = 2; i <= n; ++i) { +// auto temp = a + b; +// a = b; +// b = temp; +// } +// return b; +// } + int main(int argc, char **argv) { constexpr auto FIB20 = fibonacci(20); ASSERT(FIB20 == 6765, "fibonacci(20) should be 6765"); From e4797eb35ad8ede8026db2bc2fb26e76302f7d87 Mon Sep 17 00:00:00 2001 From: albert12345 <1528760260@qq.com> Date: Mon, 21 Jul 2025 15:28:06 +0800 Subject: [PATCH 06/17] Update all changes in submodule learning-cxx --- exercises/05_constexpr/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/05_constexpr/main.cpp b/exercises/05_constexpr/main.cpp index d42c5b3ee..681dbefda 100644 --- a/exercises/05_constexpr/main.cpp +++ b/exercises/05_constexpr/main.cpp @@ -30,7 +30,7 @@ int main(int argc, char **argv) { // TODO: 观察错误信息,修改一处,使代码编译运行 // PS: 编译运行,但是不一定能算出结果…… constexpr auto ANS_N = 90; - constexpr auto ANS = fibonacci(ANS_N); + auto ANS = fibonacci(ANS_N); std::cout << "fibonacci(" << ANS_N << ") = " << ANS << std::endl; return 0; From 0a359b22e422fd2b081129cd656f216e48d33e06 Mon Sep 17 00:00:00 2001 From: albert12345 <1528760260@qq.com> Date: Mon, 21 Jul 2025 15:58:42 +0800 Subject: [PATCH 07/17] Update all changes in submodule learning-cxx --- exercises/05_constexpr/main.cpp | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/exercises/05_constexpr/main.cpp b/exercises/05_constexpr/main.cpp index 681dbefda..2474ff6a7 100644 --- a/exercises/05_constexpr/main.cpp +++ b/exercises/05_constexpr/main.cpp @@ -1,27 +1,27 @@ #include "../exercise.h" -constexpr unsigned long long fibonacci(int i) { - switch (i) { - case 0: - return 0; - case 1: - return 1; - default: - return fibonacci(i - 1) + fibonacci(i - 2); - } -} - -// constexpr unsigned long long fibonacci(int n) { -// if (n <= 1) return n; -// unsigned long long a = 0, b = 1; -// for (int i = 2; i <= n; ++i) { -// auto temp = a + b; -// a = b; -// b = temp; +// constexpr unsigned long long fibonacci(int i) { +// switch (i) { +// case 0: +// return 0; +// case 1: +// return 1; +// default: +// return fibonacci(i - 1) + fibonacci(i - 2); // } -// return b; // } +constexpr unsigned long long fibonacci(int n) { + if (n <= 1) return n; + unsigned long long a = 0, b = 1; + for (int i = 2; i <= n; ++i) { + auto temp = a + b; + a = b; + b = temp; + } + return b; +} + int main(int argc, char **argv) { constexpr auto FIB20 = fibonacci(20); ASSERT(FIB20 == 6765, "fibonacci(20) should be 6765"); From 6b615bedff4890e4b9a29dbc89e6d1039b376dc0 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sat, 16 Aug 2025 18:12:46 +0800 Subject: [PATCH 08/17] Update all changes in submodule learning-cxx --- exercises/06_array/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/06_array/main.cpp b/exercises/06_array/main.cpp index 61ed99ec0..07e7ea883 100644 --- a/exercises/06_array/main.cpp +++ b/exercises/06_array/main.cpp @@ -11,13 +11,13 @@ unsigned long long fibonacci(int i) { return 1; default: // TODO: 补全三目表达式缺失的部分 - return ? : (arr[i] = fibonacci(i - 1) + fibonacci(i - 2)); + return arr[i] ? arr[i] : (arr[i] = fibonacci(i - 1) + fibonacci(i - 2)); } } int main(int argc, char **argv) { // TODO: 为此 ASSERT 填写正确的值 - ASSERT(sizeof(arr) == ?, "sizeof array is size of all its elements"); + ASSERT(sizeof(arr) == 90 * sizeof(unsigned long long), "sizeof array is size of all its elements"); // ---- 不要修改以下代码 ---- ASSERT(fibonacci(2) == 1, "fibonacci(2) should be 1"); ASSERT(fibonacci(20) == 6765, "fibonacci(20) should be 6765"); From ca47ded8a4f412bf23d3f18a96f847b6ce771b79 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sat, 16 Aug 2025 18:57:45 +0800 Subject: [PATCH 09/17] Update all changes in submodule learning-cxx --- exercises/07_loop/main.cpp | 5 +++-- exercises/08_pointer/main.cpp | 6 ++++++ exercises/09_enum&union/main.cpp | 2 +- exercises/10_trivial/main.cpp | 11 ++++++++--- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/exercises/07_loop/main.cpp b/exercises/07_loop/main.cpp index 44fd835cd..97133a98a 100644 --- a/exercises/07_loop/main.cpp +++ b/exercises/07_loop/main.cpp @@ -5,9 +5,10 @@ // READ: 纯函数 static unsigned long long fibonacci(int i) { // TODO: 为缓存设置正确的初始值 - static unsigned long long cache[96], cached; + static unsigned long long cache[96]{0, 1}; // TODO: 设置正确的循环条件 - for (; false; ++cached) { + static int cached = 2; + for (; cached <= i; ++cached) { cache[cached] = cache[cached - 1] + cache[cached - 2]; } return cache[i]; diff --git a/exercises/08_pointer/main.cpp b/exercises/08_pointer/main.cpp index ba37173f5..78c7deeed 100644 --- a/exercises/08_pointer/main.cpp +++ b/exercises/08_pointer/main.cpp @@ -5,6 +5,12 @@ bool is_fibonacci(int *ptr, int len, int stride) { ASSERT(len >= 3, "`len` should be at least 3"); // TODO: 编写代码判断从 ptr 开始,每 stride 个元素取 1 个元素,组成长度为 n 的数列是否满足 // arr[i + 2] = arr[i] + arr[i + 1] + for (int i = 0; i + 2 < len; ++i) { + int a = *(ptr + i * stride); + int b = *(ptr + (i + 1) * stride); + int c = *(ptr + (i + 2) * stride); + if (a + b != c) return false; + } return true; } diff --git a/exercises/09_enum&union/main.cpp b/exercises/09_enum&union/main.cpp index 3f2cec768..7f9104283 100644 --- a/exercises/09_enum&union/main.cpp +++ b/exercises/09_enum&union/main.cpp @@ -37,7 +37,7 @@ ColorEnum convert_by_pun(Color c) { TypePun pun; // TODO: 补全类型双关转换 - + pun.c = c; return pun.e; } diff --git a/exercises/10_trivial/main.cpp b/exercises/10_trivial/main.cpp index 6ba23e48e..2d5d89542 100644 --- a/exercises/10_trivial/main.cpp +++ b/exercises/10_trivial/main.cpp @@ -9,8 +9,13 @@ struct FibonacciCache { // TODO: 实现正确的缓存优化斐波那契计算 static unsigned long long fibonacci(FibonacciCache &cache, int i) { - for (; false; ++cached) { - cache[cached] = cache[cached - 1] + cache[cached - 2]; + if (cache.cached == 0) { + cache.cache[0] = 0; + cache.cache[1] = 1; + cache.cached = 2; + } + for (; cache.cached <= i; ++cache.cached) { + cache.cache[cache.cached] = cache.cache[cache.cached - 1] + cache.cache[cache.cached - 2]; } return cache.cache[i]; } @@ -19,7 +24,7 @@ int main(int argc, char **argv) { // TODO: 初始化缓存结构体,使计算正确 // NOTICE: C/C++ 中,读取未初始化的变量(包括结构体变量)是未定义行为 // READ: 初始化的各种写法 - FibonacciCache fib; + FibonacciCache fib{}; ASSERT(fibonacci(fib, 10) == 55, "fibonacci(10) should be 55"); std::cout << "fibonacci(10) = " << fibonacci(fib, 10) << std::endl; return 0; From 5685f8790020f5e90908c207c964e6508b320de4 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sat, 16 Aug 2025 21:22:55 +0800 Subject: [PATCH 10/17] Update all changes in submodule learning-cxx --- exercises/11_method/main.cpp | 4 +- exercises/12_method_const/main.cpp | 6 ++- exercises/13_class/main.cpp | 4 +- exercises/14_class_destruct/main.cpp | 15 ++++++-- exercises/15_class_clone/main.cpp | 21 ++++++++-- exercises/16_class_move/main.cpp | 36 +++++++++++++++--- exercises/17_class_derive/main.cpp | 6 +-- exercises/18_class_virtual/main.cpp | 40 ++++++++++---------- exercises/19_class_virtual_destruct/main.cpp | 25 ++++++------ exercises/20_function_template/main.cpp | 6 ++- exercises/21_runtime_datatype/main.cpp | 13 ++++++- 11 files changed, 122 insertions(+), 54 deletions(-) diff --git a/exercises/11_method/main.cpp b/exercises/11_method/main.cpp index 0e08e0a36..b03bb11b7 100644 --- a/exercises/11_method/main.cpp +++ b/exercises/11_method/main.cpp @@ -3,10 +3,10 @@ struct Fibonacci { unsigned long long cache[128]; int cached; - + Fibonacci() : cache{0, 1}, cached(2) {} // TODO: 实现正确的缓存优化斐波那契计算 unsigned long long get(int i) { - for (; false; ++cached) { + for (; cached <= i; ++cached) { cache[cached] = cache[cached - 1] + cache[cached - 2]; } return cache[i]; diff --git a/exercises/12_method_const/main.cpp b/exercises/12_method_const/main.cpp index 5521be4da..36ed8c28c 100644 --- a/exercises/12_method_const/main.cpp +++ b/exercises/12_method_const/main.cpp @@ -5,7 +5,11 @@ struct Fibonacci { int numbers[11]; // TODO: 修改方法签名和实现,使测试通过 - int get(int i) { + // int get(int i) { + // } + // 修改为 constexpr const 成员函数,支持编译期调用 + constexpr int get(int i) const { + return numbers[i]; } }; diff --git a/exercises/13_class/main.cpp b/exercises/13_class/main.cpp index 9afa98c5b..b53da318d 100644 --- a/exercises/13_class/main.cpp +++ b/exercises/13_class/main.cpp @@ -15,10 +15,10 @@ class Fibonacci { public: // TODO: 实现构造器 // Fibonacci() - + Fibonacci() : cache{0, 1}, cached(2) {} // TODO: 实现正确的缓存优化斐波那契计算 size_t get(int i) { - for (; false; ++cached) { + for (; cached <= i; ++cached) { cache[cached] = cache[cached - 1] + cache[cached - 2]; } return cache[i]; diff --git a/exercises/14_class_destruct/main.cpp b/exercises/14_class_destruct/main.cpp index 42150e8ca..9beca9cc1 100644 --- a/exercises/14_class_destruct/main.cpp +++ b/exercises/14_class_destruct/main.cpp @@ -8,17 +8,26 @@ class DynFibonacci { size_t *cache; int cached; + int capacity; // 缓存容量(用于防止越界) public: // TODO: 实现动态设置容量的构造器 - DynFibonacci(int capacity): cache(new ?), cached(?) {} + DynFibonacci(int capacity) + : cache(new size_t[capacity]), cached(2), capacity(capacity) { + cache[0] = 0; + cache[1] = 1; + } // TODO: 实现析构器,释放缓存空间 - ~DynFibonacci(); + ~DynFibonacci() { + delete[] cache; + } // TODO: 实现正确的缓存优化斐波那契计算 size_t get(int i) { - for (; false; ++cached) { + ASSERT(i < capacity, "Index out of bounds"); + + for (; cached <= i; ++cached) { cache[cached] = cache[cached - 1] + cache[cached - 2]; } return cache[i]; diff --git a/exercises/15_class_clone/main.cpp b/exercises/15_class_clone/main.cpp index f74b70391..8c8fdec41 100644 --- a/exercises/15_class_clone/main.cpp +++ b/exercises/15_class_clone/main.cpp @@ -7,20 +7,33 @@ class DynFibonacci { size_t *cache; int cached; + int capacity; public: // TODO: 实现动态设置容量的构造器 - DynFibonacci(int capacity): cache(new ?), cached(?) {} + DynFibonacci(int capacity) + : cache(new size_t[capacity]), cached(2), capacity(capacity) { + cache[0] = 0; + cache[1] = 1; + } // TODO: 实现复制构造器 - DynFibonacci(DynFibonacci const &) = delete; + DynFibonacci(DynFibonacci const &other) + : cache(new size_t[other.capacity]), cached(other.cached), capacity(other.capacity) { + for (int i = 0; i < cached; ++i) { + cache[i] = other.cache[i]; + } + } // TODO: 实现析构器,释放缓存空间 - ~DynFibonacci(); + ~DynFibonacci() { + delete[] cache; + } // TODO: 实现正确的缓存优化斐波那契计算 size_t get(int i) { - for (; false; ++cached) { + ASSERT(i < capacity, "i out of bounds"); + for (; cached <= i; ++cached) { cache[cached] = cache[cached - 1] + cache[cached - 2]; } return cache[i]; diff --git a/exercises/16_class_move/main.cpp b/exercises/16_class_move/main.cpp index 8d2c421da..ec5d6bf81 100644 --- a/exercises/16_class_move/main.cpp +++ b/exercises/16_class_move/main.cpp @@ -12,24 +12,50 @@ class DynFibonacci { size_t *cache; int cached; + int capacity; public: // TODO: 实现动态设置容量的构造器 - DynFibonacci(int capacity): cache(new ?), cached(?) {} + DynFibonacci(int capacity) + : cache(new size_t[capacity]), cached(2), capacity(capacity) { + cache[0] = 0; + cache[1] = 1; + } // TODO: 实现移动构造器 - DynFibonacci(DynFibonacci &&) noexcept = delete; + DynFibonacci(DynFibonacci &&other) noexcept + : cache(other.cache), cached(other.cached), capacity(other.capacity) { + other.cache = nullptr; + other.cached = 0; + other.capacity = 0; + } // TODO: 实现移动赋值 // NOTICE: ⚠ 注意移动到自身问题 ⚠ - DynFibonacci &operator=(DynFibonacci &&) noexcept = delete; + DynFibonacci &operator=(DynFibonacci &&other) noexcept { + if (this != &other) { + delete[] cache; + + cache = other.cache; + cached = other.cached; + capacity = other.capacity; + + other.cache = nullptr; + other.cached = 0; + other.capacity = 0; + } + return *this; + } // TODO: 实现析构器,释放缓存空间 - ~DynFibonacci(); + ~DynFibonacci() { + delete[] cache; + } // TODO: 实现正确的缓存优化斐波那契计算 size_t operator[](int i) { - for (; false; ++cached) { + ASSERT(i < capacity, "Index out of bounds"); + for (; cached <= i; ++cached) { cache[cached] = cache[cached - 1] + cache[cached - 2]; } return cache[i]; diff --git a/exercises/17_class_derive/main.cpp b/exercises/17_class_derive/main.cpp index 819ae72fc..0c245df4f 100644 --- a/exercises/17_class_derive/main.cpp +++ b/exercises/17_class_derive/main.cpp @@ -50,9 +50,9 @@ int main(int argc, char **argv) { B b = B(3); // TODO: 补全三个类型的大小 - static_assert(sizeof(X) == ?, "There is an int in X"); - static_assert(sizeof(A) == ?, "There is an int in A"); - static_assert(sizeof(B) == ?, "B is an A with an X"); + static_assert(sizeof(X) == 4, "There is an int in X"); + static_assert(sizeof(A) == 4, "There is an int in A"); + static_assert(sizeof(B) == 8, "B is an A with an X"); i = 0; std::cout << std::endl diff --git a/exercises/18_class_virtual/main.cpp b/exercises/18_class_virtual/main.cpp index ac6382413..344709e4c 100644 --- a/exercises/18_class_virtual/main.cpp +++ b/exercises/18_class_virtual/main.cpp @@ -42,38 +42,38 @@ int main(int argc, char **argv) { C c; D d; - ASSERT(a.virtual_name() == '?', MSG); - ASSERT(b.virtual_name() == '?', MSG); - ASSERT(c.virtual_name() == '?', MSG); - ASSERT(d.virtual_name() == '?', MSG); - ASSERT(a.direct_name() == '?', MSG); - ASSERT(b.direct_name() == '?', MSG); - ASSERT(c.direct_name() == '?', MSG); - ASSERT(d.direct_name() == '?', MSG); + ASSERT(a.virtual_name() == 'A', MSG); + ASSERT(b.virtual_name() == 'B', MSG); + ASSERT(c.virtual_name() == 'C', MSG); + ASSERT(d.virtual_name() == 'C', MSG); + ASSERT(a.direct_name() == 'A', MSG); + ASSERT(b.direct_name() == 'B', MSG); + ASSERT(c.direct_name() == 'C', MSG); + ASSERT(d.direct_name() == 'D', MSG); A &rab = b; B &rbc = c; C &rcd = d; - ASSERT(rab.virtual_name() == '?', MSG); - ASSERT(rbc.virtual_name() == '?', MSG); - ASSERT(rcd.virtual_name() == '?', MSG); - ASSERT(rab.direct_name() == '?', MSG); - ASSERT(rbc.direct_name() == '?', MSG); - ASSERT(rcd.direct_name() == '?', MSG); + ASSERT(rab.virtual_name() == 'B', MSG); + ASSERT(rbc.virtual_name() == 'C', MSG); + ASSERT(rcd.virtual_name() == 'C', MSG); + ASSERT(rab.direct_name() == 'A', MSG); + ASSERT(rbc.direct_name() == 'B', MSG); + ASSERT(rcd.direct_name() == 'C', MSG); A &rac = c; B &rbd = d; - ASSERT(rac.virtual_name() == '?', MSG); - ASSERT(rbd.virtual_name() == '?', MSG); - ASSERT(rac.direct_name() == '?', MSG); - ASSERT(rbd.direct_name() == '?', MSG); + ASSERT(rac.virtual_name() == 'C', MSG); + ASSERT(rbd.virtual_name() == 'C', MSG); + ASSERT(rac.direct_name() == 'A', MSG); + ASSERT(rbd.direct_name() == 'B', MSG); A &rad = d; - ASSERT(rad.virtual_name() == '?', MSG); - ASSERT(rad.direct_name() == '?', MSG); + ASSERT(rad.virtual_name() == 'C', MSG); + ASSERT(rad.direct_name() == 'A', MSG); return 0; } diff --git a/exercises/19_class_virtual_destruct/main.cpp b/exercises/19_class_virtual_destruct/main.cpp index cdd54f74f..99579d4e0 100644 --- a/exercises/19_class_virtual_destruct/main.cpp +++ b/exercises/19_class_virtual_destruct/main.cpp @@ -10,7 +10,7 @@ struct A { A() { ++num_a; } - ~A() { + virtual ~A() { // 必须是虚析构 --num_a; } @@ -18,14 +18,16 @@ struct A { return 'A'; } }; +int A::num_a = 0; // ⚠️ 静态变量定义必须放类外 + struct B final : public A { // TODO: 正确初始化静态字段 - static int num_b = 0; + static int num_b; B() { ++num_b; } - ~B() { + ~B() override { // 虚析构在 A 中已经定义,此处 override --num_b; } @@ -33,14 +35,15 @@ struct B final : public A { return 'B'; } }; +int B::num_b = 0; // ⚠️ 类外初始化 int main(int argc, char **argv) { auto a = new A; auto b = new B; - ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a"); - ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b"); - ASSERT(a->name() == '?', "Fill in the correct value for a->name()"); - ASSERT(b->name() == '?', "Fill in the correct value for b->name()"); + ASSERT(A::num_a == 2, "Fill in the correct value for A::num_a"); + ASSERT(B::num_b == 1, "Fill in the correct value for B::num_b"); + ASSERT(a->name() == 'A', "Fill in the correct value for a->name()"); + ASSERT(b->name() == 'B', "Fill in the correct value for b->name()"); delete a; delete b; @@ -48,13 +51,13 @@ int main(int argc, char **argv) { ASSERT(B::num_b == 0, "Every B was destroyed"); A *ab = new B;// 派生类指针可以随意转换为基类指针 - ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a"); - ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b"); - ASSERT(ab->name() == '?', "Fill in the correct value for ab->name()"); + ASSERT(A::num_a == 1, "Fill in the correct value for A::num_a"); + ASSERT(B::num_b == 1, "Fill in the correct value for B::num_b"); + ASSERT(ab->name() == 'B', "Fill in the correct value for ab->name()"); // TODO: 基类指针无法随意转换为派生类指针,补全正确的转换语句 B &bb = *ab; - ASSERT(bb.name() == '?', "Fill in the correct value for bb->name()"); + ASSERT(bb.name() == 'B', "Fill in the correct value for bb->name()"); // TODO: ---- 以下代码不要修改,通过改正类定义解决编译问题 ---- delete ab;// 通过指针可以删除指向的对象,即使是多态对象 diff --git a/exercises/20_function_template/main.cpp b/exercises/20_function_template/main.cpp index cb6d978d3..4abc7e34e 100644 --- a/exercises/20_function_template/main.cpp +++ b/exercises/20_function_template/main.cpp @@ -2,7 +2,8 @@ // READ: 函数模板 // TODO: 将这个函数模板化 -int plus(int a, int b) { +template +T plus(T a, T b) { return a + b; } @@ -14,7 +15,8 @@ int main(int argc, char **argv) { ASSERT(plus(1.25f, 2.5f) == 3.75f, "Plus two float"); ASSERT(plus(1.25, 2.5) == 3.75, "Plus two double"); // TODO: 修改判断条件使测试通过 - ASSERT(plus(0.1, 0.2) == 0.3, "How to make this pass?"); + // 使用误差容忍判断浮点数 + ASSERT(std::abs(plus(0.1, 0.2) - 0.3) < 1e-9, "How to make this pass?"); return 0; } diff --git a/exercises/21_runtime_datatype/main.cpp b/exercises/21_runtime_datatype/main.cpp index 9c4bf376a..aaed5d31e 100644 --- a/exercises/21_runtime_datatype/main.cpp +++ b/exercises/21_runtime_datatype/main.cpp @@ -18,13 +18,24 @@ struct TaggedUnion { }; // TODO: 将这个函数模板化用于 sigmoid_dyn -float sigmoid(float x) { +// 模板化 sigmoid 函数,支持 float 与 double +template +T sigmoid(T x) { return 1 / (1 + std::exp(-x)); } +// 动态派发 sigmoid TaggedUnion sigmoid_dyn(TaggedUnion x) { TaggedUnion ans{x.type}; // TODO: 根据 type 调用 sigmoid + switch (x.type) { + case DataType::Float: + ans.f = sigmoid(x.f); + break; + case DataType::Double: + ans.d = sigmoid(x.d); + break; + } return ans; } From 174bd4b4ec2e65d870afa0978b5669a4fe8c1a88 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sun, 17 Aug 2025 09:41:27 +0800 Subject: [PATCH 11/17] Update all changes in submodule learning-cxx --- exercises/22_class_template/main.cpp | 38 ++++++++++++++ exercises/23_template_const/main.cpp | 9 +++- exercises/24_std_array/main.cpp | 16 +++--- exercises/25_std_vector/main.cpp | 74 ++++++++++++++------------- exercises/26_std_vector_bool/main.cpp | 21 ++++---- exercises/27_strides/main.cpp | 9 ++-- exercises/28_std_string/main.cpp | 6 +-- exercises/29_std_map/main.cpp | 6 ++- exercises/30_std_unique_ptr/main.cpp | 4 +- exercises/31_std_shared_ptr/main.cpp | 46 ++++++++--------- exercises/32_std_transform/main.cpp | 7 ++- exercises/33_std_accumulate/main.cpp | 2 + 12 files changed, 149 insertions(+), 89 deletions(-) diff --git a/exercises/22_class_template/main.cpp b/exercises/22_class_template/main.cpp index d4985d904..fe96bdd8a 100644 --- a/exercises/22_class_template/main.cpp +++ b/exercises/22_class_template/main.cpp @@ -10,6 +10,10 @@ struct Tensor4D { Tensor4D(unsigned int const shape_[4], T const *data_) { unsigned int size = 1; // TODO: 填入正确的 shape 并计算 size + for (int i = 0; i < 4; ++i) { + shape[i] = shape_[i]; + size *= shape_[i]; + } data = new T[size]; std::memcpy(data, data_, size * sizeof(T)); } @@ -28,6 +32,40 @@ struct Tensor4D { // 则 `this` 与 `others` 相加时,3 个形状为 `[1, 2, 1, 4]` 的子张量各自与 `others` 对应项相加。 Tensor4D &operator+=(Tensor4D const &others) { // TODO: 实现单向广播的加法 +unsigned int total = 1; + for (int i = 0; i < 4; ++i) { + ASSERT(others.shape[i] == 1 || others.shape[i] == shape[i], "Broadcast shape mismatch"); + total *= shape[i]; + } + + // 计算 strides(行主序,4维) + unsigned int self_stride[4]; + unsigned int other_stride[4]; + self_stride[3] = 1; + other_stride[3] = (others.shape[3] == 1) ? 0 : 1; + for (int i = 2; i >= 0; --i) { + self_stride[i] = self_stride[i + 1] * shape[i + 1]; + other_stride[i] = (others.shape[i] == 1) ? 0 : other_stride[i + 1] * others.shape[i + 1]; + } + + // 广播加法 + for (unsigned int i = 0; i < total; ++i) { + // 解码4D索引 + unsigned int idx = i; + unsigned int coord[4]; + for (int j = 0; j < 4; ++j) { + coord[j] = idx / self_stride[j]; + idx %= self_stride[j]; + } + + // 计算 other 的 index + unsigned int o_idx = 0; + for (int j = 0; j < 4; ++j) { + o_idx += coord[j] * other_stride[j]; + } + + data[i] += others.data[o_idx]; + } return *this; } }; diff --git a/exercises/23_template_const/main.cpp b/exercises/23_template_const/main.cpp index e0105e168..6fa3e4f5d 100644 --- a/exercises/23_template_const/main.cpp +++ b/exercises/23_template_const/main.cpp @@ -10,6 +10,10 @@ struct Tensor { Tensor(unsigned int const shape_[N]) { unsigned int size = 1; + for (unsigned int i = 0; i < N; ++i) { + shape[i] = shape_[i]; + size *= shape[i]; + } // TODO: 填入正确的 shape 并计算 size data = new T[size]; std::memset(data, 0, size * sizeof(T)); @@ -32,9 +36,12 @@ struct Tensor { private: unsigned int data_index(unsigned int const indices[N]) const { unsigned int index = 0; - for (unsigned int i = 0; i < N; ++i) { + unsigned int stride = 1; + for (int i = N - 1; i >= 0; --i) { ASSERT(indices[i] < shape[i], "Invalid index"); // TODO: 计算 index + index += indices[i] * stride; + stride *= shape[i]; } return index; } diff --git a/exercises/24_std_array/main.cpp b/exercises/24_std_array/main.cpp index c29718d9d..1d645c8d4 100644 --- a/exercises/24_std_array/main.cpp +++ b/exercises/24_std_array/main.cpp @@ -8,21 +8,21 @@ int main(int argc, char **argv) { { std::array arr{{1, 2, 3, 4, 5}}; - ASSERT(arr.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(arr) == ?, "Fill in the correct value."); + ASSERT(arr.size() == 5, "Fill in the correct value."); + ASSERT(sizeof(arr) == sizeof(int) * 5, "Fill in the correct value."); int ans[]{1, 2, 3, 4, 5}; - ASSERT(std::memcmp(arr.?, ans, ?) == 0, "Fill in the correct values."); + ASSERT(std::memcmp(arr.data(), ans, sizeof(ans)) == 0, "Fill in the correct values."); } { std::array arr; - ASSERT(arr.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(arr) == ?, "Fill in the correct value."); + ASSERT(arr.size() == 8, "Fill in the correct value."); + ASSERT(sizeof(arr) == sizeof(double) * 8, "Fill in the correct value."); } { std::array arr{"Hello, InfiniTensor!"}; - ASSERT(arr.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(arr) == ?, "Fill in the correct value."); - ASSERT(std::strcmp(arr.?, "Hello, InfiniTensor!") == 0, "Fill in the correct value."); + ASSERT(arr.size() == 21, "Fill in the correct value."); + ASSERT(sizeof(arr) == sizeof(char) * 21, "Fill in the correct value."); + ASSERT(std::strcmp(arr.data(), "Hello, InfiniTensor!") == 0, "Fill in the correct value."); } return 0; } diff --git a/exercises/25_std_vector/main.cpp b/exercises/25_std_vector/main.cpp index f9e41bb78..047067e1f 100644 --- a/exercises/25_std_vector/main.cpp +++ b/exercises/25_std_vector/main.cpp @@ -8,81 +8,83 @@ int main(int argc, char **argv) { { std::vector vec{1, 2, 3, 4, 5}; - ASSERT(vec.size() == ?, "Fill in the correct value."); + ASSERT(vec.size() == 5, "Fill in the correct value."); // THINK: `std::vector` 的大小是什么意思?与什么有关? - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + // sizeof(vec) 是 vector 类对象本身的大小,不包括数据容量 + ASSERT(sizeof(vec) == sizeof(std::vector), "Fill in the correct value."); int ans[]{1, 2, 3, 4, 5}; - ASSERT(std::memcmp(vec.?, ans, sizeof(ans)) == 0, "Fill in the correct values."); + ASSERT(std::memcmp(vec.data(), ans, sizeof(ans)) == 0, "Fill in the correct values."); } { std::vector vec{1, 2, 3, 4, 5}; { - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(vec.size() == 5, "Fill in the correct value."); + ASSERT(sizeof(vec) == sizeof(std::vector), "Fill in the correct value."); double ans[]{1, 2, 3, 4, 5}; - ASSERT(std::memcmp(vec.?, ans, sizeof(ans)) == 0, "Fill in the correct values."); + ASSERT(std::memcmp(vec.data(), ans, sizeof(ans)) == 0, "Fill in the correct values."); } { vec.push_back(6); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(vec.size() == 6, "Fill in the correct value."); + ASSERT(sizeof(vec) == sizeof(std::vector), "Fill in the correct value."); vec.pop_back(); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(vec.size() == 5, "Fill in the correct value."); + ASSERT(sizeof(vec) == sizeof(std::vector), "Fill in the correct value."); } { vec[4] = 6; - ASSERT(vec[0] == ?, "Fill in the correct value."); - ASSERT(vec[1] == ?, "Fill in the correct value."); - ASSERT(vec[2] == ?, "Fill in the correct value."); - ASSERT(vec[3] == ?, "Fill in the correct value."); - ASSERT(vec[4] == ?, "Fill in the correct value."); + ASSERT(vec[0] == 1, "Fill in the correct value."); + ASSERT(vec[1] == 2, "Fill in the correct value."); + ASSERT(vec[2] == 3, "Fill in the correct value."); + ASSERT(vec[3] == 4, "Fill in the correct value."); + ASSERT(vec[4] == 6, "Fill in the correct value."); } { // THINK: `std::vector` 插入删除的时间复杂度是什么? - vec.insert(?, 1.5); + // 插入位置在开头,时间复杂度 O(n) + vec.insert(vec.begin() + 1, 1.5); ASSERT((vec == std::vector{1, 1.5, 2, 3, 4, 6}), "Make this assertion pass."); - vec.erase(?); + vec.erase(vec.begin() + 3); // 删除值为 3 的元素 ASSERT((vec == std::vector{1, 1.5, 2, 4, 6}), "Make this assertion pass."); } { - vec.shrink_to_fit(); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); + vec.shrink_to_fit(); // 容量缩减到正好大小 + ASSERT(vec.capacity() == vec.size(), "Fill in the correct value."); vec.clear(); ASSERT(vec.empty(), "`vec` is empty now."); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); + ASSERT(vec.size() == 0, "Fill in the correct value."); + ASSERT(vec.capacity() == 5, "Fill in the correct value."); // 容量不变 } } { - std::vector vec(?, ?); // TODO: 调用正确的构造函数 + std::vector vec(48, 'z'); // TODO: 调用正确的构造函数 ASSERT(vec[0] == 'z', "Make this assertion pass."); ASSERT(vec[47] == 'z', "Make this assertion pass."); ASSERT(vec.size() == 48, "Make this assertion pass."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(sizeof(vec) == sizeof(std::vector), "Fill in the correct value."); { auto capacity = vec.capacity(); - vec.resize(16); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in a correct identifier."); + vec.resize(16); // 缩小 size,不影响 capacity + ASSERT(vec.size() == 16, "Fill in the correct value."); + ASSERT(vec.capacity() == capacity, "Fill in a correct identifier."); } { - vec.reserve(256); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); + vec.reserve(256); // 提前分配更大的内存 + ASSERT(vec.size() == 16, "Fill in the correct value."); + ASSERT(vec.capacity() == 256, "Fill in the correct value."); } { vec.push_back('a'); vec.push_back('b'); vec.push_back('c'); vec.push_back('d'); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); - ASSERT(vec[15] == ?, "Fill in the correct value."); - ASSERT(vec[?] == 'a', "Fill in the correct value."); - ASSERT(vec[?] == 'b', "Fill in the correct value."); - ASSERT(vec[?] == 'c', "Fill in the correct value."); - ASSERT(vec[?] == 'd', "Fill in the correct value."); + ASSERT(vec.size() == 20, "Fill in the correct value."); + ASSERT(vec.capacity() == 256, "Fill in the correct value."); + ASSERT(vec[15] == 'z', "Fill in the correct value."); + ASSERT(vec[16] == 'a', "Fill in the correct value."); + ASSERT(vec[17] == 'b', "Fill in the correct value."); + ASSERT(vec[18] == 'c', "Fill in the correct value."); + ASSERT(vec[19] == 'd', "Fill in the correct value."); } } diff --git a/exercises/26_std_vector_bool/main.cpp b/exercises/26_std_vector_bool/main.cpp index b4ab4f9c4..47ce69630 100644 --- a/exercises/26_std_vector_bool/main.cpp +++ b/exercises/26_std_vector_bool/main.cpp @@ -4,31 +4,32 @@ // READ: std::vector // READ: 模板特化 -// TODO: 将下列 `?` 替换为正确的代码 int main(int argc, char **argv) { - std::vector vec(?, ?);// TODO: 正确调用构造函数 + std::vector vec(100, true); // TODO: 正确调用构造函数 ASSERT(vec[0], "Make this assertion pass."); ASSERT(vec[99], "Make this assertion pass."); ASSERT(vec.size() == 100, "Make this assertion pass."); + // NOTICE: 平台相关!注意 CI:Ubuntu 上的值。 std::cout << "sizeof(std::vector) = " << sizeof(std::vector) << std::endl; - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(sizeof(vec) == sizeof(std::vector), "Fill in the correct value."); + { vec[20] = false; - ASSERT(?vec[20], "Fill in `vec[20]` or `!vec[20]`."); + ASSERT(!vec[20], "Fill in `vec[20]` or `!vec[20]`."); } { vec.push_back(false); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(?vec[100], "Fill in `vec[100]` or `!vec[100]`."); + ASSERT(vec.size() == 101, "Fill in the correct value."); + ASSERT(!vec[100], "Fill in `vec[100]` or `!vec[100]`."); } { - auto ref = vec[30]; - ASSERT(?ref, "Fill in `ref` or `!ref`"); + auto ref = vec[30]; // 注意这里返回的是 std::vector::reference(代理类) + ASSERT(ref, "Fill in `ref` or `!ref`"); ref = false; - ASSERT(?ref, "Fill in `ref` or `!ref`"); + ASSERT(!ref, "Fill in `ref` or `!ref`"); // THINK: WHAT and WHY? - ASSERT(?vec[30], "Fill in `vec[30]` or `!vec[30]`."); + ASSERT(!vec[30], "Fill in `vec[30]` or `!vec[30]`."); } return 0; } diff --git a/exercises/27_strides/main.cpp b/exercises/27_strides/main.cpp index baceaf2a9..f85e60a55 100644 --- a/exercises/27_strides/main.cpp +++ b/exercises/27_strides/main.cpp @@ -15,9 +15,12 @@ using udim = unsigned int; /// @return 张量每维度的访问步长 std::vector strides(std::vector const &shape) { std::vector strides(shape.size()); - // TODO: 完成函数体,根据张量形状计算张量连续存储时的步长。 - // READ: 逆向迭代器 std::vector::rbegin - // 使用逆向迭代器可能可以简化代码 + udim stride = 1; + // 从最后一维开始逆向计算步长 + for (int i = static_cast(shape.size()) - 1; i >= 0; --i) { + strides[i] = stride; + stride *= shape[i]; // 累积形状元素,作为前一维的步长 + } return strides; } diff --git a/exercises/28_std_string/main.cpp b/exercises/28_std_string/main.cpp index d8b276274..5ca96a9ee 100644 --- a/exercises/28_std_string/main.cpp +++ b/exercises/28_std_string/main.cpp @@ -10,9 +10,9 @@ int main(int argc, char **argv) { auto world = "world"; // READ: `decltype` 表达式 // READ: `std::is_same_v` 元编程判别 - ASSERT((std::is_same_v), "Fill in the missing type."); - ASSERT((std::is_same_v), "Fill in the missing type."); + ASSERT((std::is_same_v), "Fill in the missing type."); + ASSERT((std::is_same_v), "Fill in the missing type."); // TODO: 将 `?` 替换为正确的字符串 - ASSERT(hello + ", " + world + '!' == "?", "Fill in the missing string."); + ASSERT(hello + ", " + world + '!' == "Hello, world!", "Fill in the missing string."); return 0; } diff --git a/exercises/29_std_map/main.cpp b/exercises/29_std_map/main.cpp index fcccca347..2997390b0 100644 --- a/exercises/29_std_map/main.cpp +++ b/exercises/29_std_map/main.cpp @@ -6,12 +6,14 @@ template bool key_exists(std::map const &map, k const &key) { - // TODO: 实现函数 + // 使用 count 或 find 判断 key 是否存在 + return map.find(key) != map.end(); } template void set(std::map &map, k key, v value) { - // TODO: 实现函数 + // 插入或更新键值对 + map[key] = value; } // ---- 不要修改以下代码 ---- diff --git a/exercises/30_std_unique_ptr/main.cpp b/exercises/30_std_unique_ptr/main.cpp index 9b98b5794..2a3c20100 100644 --- a/exercises/30_std_unique_ptr/main.cpp +++ b/exercises/30_std_unique_ptr/main.cpp @@ -53,8 +53,8 @@ int main(int argc, char **argv) { {"fd"}, // TODO: 分析 problems[1] 中资源的生命周期,将记录填入 `std::vector` // NOTICE: 此题结果依赖对象析构逻辑,平台相关,提交时以 CI 实际运行平台为准 - {"", "", "", "", "", "", "", ""}, - {"", "", "", "", "", "", "", ""}, + {"ffr", "d", "", "", "", "", "", ""}, + {"r", "d", "r", "d", "", "", "", ""}, }; // ---- 不要修改以下代码 ---- diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index febbbcc6f..a1eb9c36a 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -6,40 +6,40 @@ // TODO: 将下列 `?` 替换为正确的值 int main(int argc, char **argv) { - auto shared = std::make_shared(10); - std::shared_ptr ptrs[]{shared, shared, shared}; + auto shared = std::make_shared(10); // use_count = 1 + std::shared_ptr ptrs[]{shared, shared, shared}; // use_count = 4 std::weak_ptr observer = shared; - ASSERT(observer.use_count() == ?, ""); + ASSERT(observer.use_count() == 4, ""); - ptrs[0].reset(); - ASSERT(observer.use_count() == ?, ""); + ptrs[0].reset(); // use_count = 3 + ASSERT(observer.use_count() == 3, ""); - ptrs[1] = nullptr; - ASSERT(observer.use_count() == ?, ""); + ptrs[1] = nullptr; // use_count = 2 + ASSERT(observer.use_count() == 2, ""); - ptrs[2] = std::make_shared(*shared); - ASSERT(observer.use_count() == ?, ""); + ptrs[2] = std::make_shared(*shared); // 创建新对象,不影响原 shared,原 use_count = 1 + ASSERT(observer.use_count() == 1, ""); - ptrs[0] = shared; - ptrs[1] = shared; - ptrs[2] = std::move(shared); - ASSERT(observer.use_count() == ?, ""); + ptrs[0] = shared; // use_count = 2 + ptrs[1] = shared; // use_count = 3 + ptrs[2] = std::move(shared); // shared 转交所有权给 ptrs[2],use_count 仍为 3 + ASSERT(observer.use_count() == 3, ""); - std::ignore = std::move(ptrs[0]); - ptrs[1] = std::move(ptrs[1]); - ptrs[1] = std::move(ptrs[2]); - ASSERT(observer.use_count() == ?, ""); + std::ignore = std::move(ptrs[0]); // 无副作用 + ptrs[1] = std::move(ptrs[1]); // 无副作用 + ptrs[1] = std::move(ptrs[2]); // 仍持有原对象,use_count = 3 + ASSERT(observer.use_count() == 3, ""); - shared = observer.lock(); - ASSERT(observer.use_count() == ?, ""); + shared = observer.lock(); // 锁回 shared_ptr,use_count = 4 + ASSERT(observer.use_count() == 4, ""); shared = nullptr; - for (auto &ptr : ptrs) ptr = nullptr; - ASSERT(observer.use_count() == ?, ""); + for (auto &ptr : ptrs) ptr = nullptr; // 全部释放,use_count = 0 + ASSERT(observer.use_count() == 0, ""); - shared = observer.lock(); - ASSERT(observer.use_count() == ?, ""); + shared = observer.lock(); // 对象已被释放,lock 返回 nullptr + ASSERT(observer.use_count() == 0, ""); return 0; } diff --git a/exercises/32_std_transform/main.cpp b/exercises/32_std_transform/main.cpp index f4dc25a5c..c2297ff8c 100644 --- a/exercises/32_std_transform/main.cpp +++ b/exercises/32_std_transform/main.cpp @@ -8,8 +8,13 @@ int main(int argc, char **argv) { std::vector val{8, 13, 21, 34, 55}; + // TODO: 调用 `std::transform`,将 `v` 中的每个元素乘以 2,并转换为字符串,存入 `ans` - // std::vector ans + std::vector ans(val.size()); + + std::transform(val.begin(), val.end(), ans.begin(), + [](int x) { return std::to_string(x * 2); }); + ASSERT(ans.size() == val.size(), "ans size should be equal to val size"); ASSERT(ans[0] == "16", "ans[0] should be 16"); ASSERT(ans[1] == "26", "ans[1] should be 26"); diff --git a/exercises/33_std_accumulate/main.cpp b/exercises/33_std_accumulate/main.cpp index 6326929d5..921afe11d 100644 --- a/exercises/33_std_accumulate/main.cpp +++ b/exercises/33_std_accumulate/main.cpp @@ -12,6 +12,8 @@ int main(int argc, char **argv) { // - 连续存储; // 的张量占用的字节数 // int size = + // 使用 std::accumulate 计算张量元素个数(1×3×224×224),再乘以 sizeof(DataType) + int size = std::accumulate(std::begin(shape), std::end(shape), sizeof(DataType), std::multiplies()); ASSERT(size == 602112, "4x1x3x224x224 = 602112"); return 0; } From 826364df6f34182965644220a8567a23fd59dc53 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sun, 17 Aug 2025 09:58:26 +0800 Subject: [PATCH 12/17] Update all changes in submodule learning-cxx --- exercises/19_class_virtual_destruct/main.cpp | 17 ++++----- exercises/22_class_template/main.cpp | 38 ++++++++++---------- exercises/30_std_unique_ptr/main.cpp | 2 ++ exercises/31_std_shared_ptr/main.cpp | 36 +++++++++---------- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/exercises/19_class_virtual_destruct/main.cpp b/exercises/19_class_virtual_destruct/main.cpp index 99579d4e0..2caf9ab75 100644 --- a/exercises/19_class_virtual_destruct/main.cpp +++ b/exercises/19_class_virtual_destruct/main.cpp @@ -5,12 +5,12 @@ struct A { // TODO: 正确初始化静态字段 - static int num_a = 0; + static int num_a; // 类内仅声明,类外定义初始化 A() { ++num_a; } - virtual ~A() { // 必须是虚析构 + virtual ~A() { // 需要虚析构,确保通过基类指针删除派生对象时行为正确 --num_a; } @@ -18,16 +18,14 @@ struct A { return 'A'; } }; -int A::num_a = 0; // ⚠️ 静态变量定义必须放类外 - struct B final : public A { // TODO: 正确初始化静态字段 - static int num_b; + static int num_b; // 类内仅声明,类外定义初始化 B() { ++num_b; } - ~B() override { // 虚析构在 A 中已经定义,此处 override + ~B() override { --num_b; } @@ -35,7 +33,10 @@ struct B final : public A { return 'B'; } }; -int B::num_b = 0; // ⚠️ 类外初始化 + +// —— 静态成员的类外定义与初始化 —— +int A::num_a = 0; +int B::num_b = 0; int main(int argc, char **argv) { auto a = new A; @@ -56,7 +57,7 @@ int main(int argc, char **argv) { ASSERT(ab->name() == 'B', "Fill in the correct value for ab->name()"); // TODO: 基类指针无法随意转换为派生类指针,补全正确的转换语句 - B &bb = *ab; + B &bb = dynamic_cast(*ab); ASSERT(bb.name() == 'B', "Fill in the correct value for bb->name()"); // TODO: ---- 以下代码不要修改,通过改正类定义解决编译问题 ---- diff --git a/exercises/22_class_template/main.cpp b/exercises/22_class_template/main.cpp index fe96bdd8a..e08008de9 100644 --- a/exercises/22_class_template/main.cpp +++ b/exercises/22_class_template/main.cpp @@ -32,39 +32,37 @@ struct Tensor4D { // 则 `this` 与 `others` 相加时,3 个形状为 `[1, 2, 1, 4]` 的子张量各自与 `others` 对应项相加。 Tensor4D &operator+=(Tensor4D const &others) { // TODO: 实现单向广播的加法 -unsigned int total = 1; + // 1) 形状检查(允许 others 的维度为 1 或与 this 相同) + unsigned int total = 1; for (int i = 0; i < 4; ++i) { ASSERT(others.shape[i] == 1 || others.shape[i] == shape[i], "Broadcast shape mismatch"); total *= shape[i]; } - // 计算 strides(行主序,4维) + // 2) 计算行主序 strides unsigned int self_stride[4]; unsigned int other_stride[4]; - self_stride[3] = 1; - other_stride[3] = (others.shape[3] == 1) ? 0 : 1; + self_stride[3] = 1; + other_stride[3] = (others.shape[3] == 1) ? 0u : 1u; for (int i = 2; i >= 0; --i) { - self_stride[i] = self_stride[i + 1] * shape[i + 1]; - other_stride[i] = (others.shape[i] == 1) ? 0 : other_stride[i + 1] * others.shape[i + 1]; + self_stride[i] = self_stride[i + 1] * shape[i + 1]; + // others 该维为 1 时 stride 置 0,实现广播“锁定”该维索引 + other_stride[i] = (others.shape[i] == 1) ? 0u : other_stride[i + 1] * others.shape[i + 1]; } - // 广播加法 - for (unsigned int i = 0; i < total; ++i) { - // 解码4D索引 - unsigned int idx = i; + // 3) 逐元素计算:解码 this 的线性下标为 4D 坐标,再映射到 others 的线性下标 + for (unsigned int lin = 0; lin < total; ++lin) { + unsigned int idx = lin; unsigned int coord[4]; - for (int j = 0; j < 4; ++j) { - coord[j] = idx / self_stride[j]; - idx %= self_stride[j]; + for (int d = 0; d < 4; ++d) { + coord[d] = idx / self_stride[d]; + idx %= self_stride[d]; } - - // 计算 other 的 index - unsigned int o_idx = 0; - for (int j = 0; j < 4; ++j) { - o_idx += coord[j] * other_stride[j]; + unsigned int oidx = 0; + for (int d = 0; d < 4; ++d) { + oidx += coord[d] * other_stride[d]; } - - data[i] += others.data[o_idx]; + data[lin] += others.data[oidx]; } return *this; } diff --git a/exercises/30_std_unique_ptr/main.cpp b/exercises/30_std_unique_ptr/main.cpp index 2a3c20100..f0de52115 100644 --- a/exercises/30_std_unique_ptr/main.cpp +++ b/exercises/30_std_unique_ptr/main.cpp @@ -53,7 +53,9 @@ int main(int argc, char **argv) { {"fd"}, // TODO: 分析 problems[1] 中资源的生命周期,将记录填入 `std::vector` // NOTICE: 此题结果依赖对象析构逻辑,平台相关,提交时以 CI 实际运行平台为准 + // 解释:第一次 reset 销毁 R1(记录 "ffr"),随后 drop 销毁 R2(记录 "d") {"ffr", "d", "", "", "", "", "", ""}, + // 解释:序列中先后销毁 R1("r"), R2("d"), R3("r"), R4("d") {"r", "d", "r", "d", "", "", "", ""}, }; diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index a1eb9c36a..22e4b12be 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -6,39 +6,39 @@ // TODO: 将下列 `?` 替换为正确的值 int main(int argc, char **argv) { - auto shared = std::make_shared(10); // use_count = 1 - std::shared_ptr ptrs[]{shared, shared, shared}; // use_count = 4 + auto shared = std::make_shared(10); // use_count = 1 + std::shared_ptr ptrs[]{shared, shared, shared}; // use_count = 4 (shared + 3) std::weak_ptr observer = shared; - ASSERT(observer.use_count() == 4, ""); + ASSERT(observer.use_count() == 4, ""); // 1(shared)+3(ptrs) - ptrs[0].reset(); // use_count = 3 + ptrs[0].reset(); // -1 ASSERT(observer.use_count() == 3, ""); - ptrs[1] = nullptr; // use_count = 2 + ptrs[1] = nullptr; // -1 ASSERT(observer.use_count() == 2, ""); - ptrs[2] = std::make_shared(*shared); // 创建新对象,不影响原 shared,原 use_count = 1 + ptrs[2] = std::make_shared(*shared); // ptrs[2] 指向新对象,不再共享旧对象 -> -1 ASSERT(observer.use_count() == 1, ""); - ptrs[0] = shared; // use_count = 2 - ptrs[1] = shared; // use_count = 3 - ptrs[2] = std::move(shared); // shared 转交所有权给 ptrs[2],use_count 仍为 3 - ASSERT(observer.use_count() == 3, ""); + ptrs[0] = shared; // +1 + ptrs[1] = shared; // +1 + ptrs[2] = std::move(shared); // 原 shared 空,ptrs[2] 接管 -> +1 + ASSERT(observer.use_count() == 4, ""); // use_count 回到 4 - std::ignore = std::move(ptrs[0]); // 无副作用 - ptrs[1] = std::move(ptrs[1]); // 无副作用 - ptrs[1] = std::move(ptrs[2]); // 仍持有原对象,use_count = 3 - ASSERT(observer.use_count() == 3, ""); + std::ignore = std::move(ptrs[0]); // 移走 ptrs[0],旧的 -1 + ptrs[1] = std::move(ptrs[1]); // 自己 move 给自己,不变 + ptrs[1] = std::move(ptrs[2]); // ptrs[1] 原来的释放(-1),再接管 ptrs[2](+1),总数不变 + ASSERT(observer.use_count() == 3, ""); // 现在只有 ptrs[1]、以及之前的 observer/weak,不算,实际有 3 个 shared_ptr - shared = observer.lock(); // 锁回 shared_ptr,use_count = 4 + shared = observer.lock(); // 再拿一份强引用 -> +1 ASSERT(observer.use_count() == 4, ""); - shared = nullptr; - for (auto &ptr : ptrs) ptr = nullptr; // 全部释放,use_count = 0 + shared = nullptr; // -1 + for (auto &ptr : ptrs) ptr = nullptr; // 把剩余的 ptrs 清掉 -> -2 ASSERT(observer.use_count() == 0, ""); - shared = observer.lock(); // 对象已被释放,lock 返回 nullptr + shared = observer.lock(); // 对象已析构,lock 得到 nullptr ASSERT(observer.use_count() == 0, ""); return 0; From 6d4adc8a5d55b049f1b716e359e2a12d475866d7 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sun, 17 Aug 2025 10:06:42 +0800 Subject: [PATCH 13/17] Update all changes in submodule learning-cxx --- exercises/22_class_template/main.cpp | 25 ++++++++++------ exercises/30_std_unique_ptr/main.cpp | 6 ++-- exercises/31_std_shared_ptr/main.cpp | 44 ++++++++++++++-------------- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/exercises/22_class_template/main.cpp b/exercises/22_class_template/main.cpp index e08008de9..81a3d6d6c 100644 --- a/exercises/22_class_template/main.cpp +++ b/exercises/22_class_template/main.cpp @@ -32,25 +32,32 @@ struct Tensor4D { // 则 `this` 与 `others` 相加时,3 个形状为 `[1, 2, 1, 4]` 的子张量各自与 `others` 对应项相加。 Tensor4D &operator+=(Tensor4D const &others) { // TODO: 实现单向广播的加法 - // 1) 形状检查(允许 others 的维度为 1 或与 this 相同) + // 1) 形状检查,并计算 this 总元素数 unsigned int total = 1; for (int i = 0; i < 4; ++i) { ASSERT(others.shape[i] == 1 || others.shape[i] == shape[i], "Broadcast shape mismatch"); total *= shape[i]; } - // 2) 计算行主序 strides + // 2) 计算 this 的标准行主序 stride unsigned int self_stride[4]; - unsigned int other_stride[4]; - self_stride[3] = 1; - other_stride[3] = (others.shape[3] == 1) ? 0u : 1u; + self_stride[3] = 1; + for (int i = 2; i >= 0; --i) { + self_stride[i] = self_stride[i + 1] * shape[i + 1]; + } + + // 3) 先计算 others 的“标准 stride”(忽略广播),再逐维应用“为 1 则置 0”的规则 + unsigned int other_stride_base[4]; + other_stride_base[3] = 1; for (int i = 2; i >= 0; --i) { - self_stride[i] = self_stride[i + 1] * shape[i + 1]; - // others 该维为 1 时 stride 置 0,实现广播“锁定”该维索引 - other_stride[i] = (others.shape[i] == 1) ? 0u : other_stride[i + 1] * others.shape[i + 1]; + other_stride_base[i] = other_stride_base[i + 1] * others.shape[i + 1]; + } + unsigned int other_stride[4]; + for (int i = 0; i < 4; ++i) { + other_stride[i] = (others.shape[i] == 1) ? 0u : other_stride_base[i]; } - // 3) 逐元素计算:解码 this 的线性下标为 4D 坐标,再映射到 others 的线性下标 + // 4) 逐元素:把 this 的线性下标解码为 4D 坐标,再映射到 others 的线性下标 for (unsigned int lin = 0; lin < total; ++lin) { unsigned int idx = lin; unsigned int coord[4]; diff --git a/exercises/30_std_unique_ptr/main.cpp b/exercises/30_std_unique_ptr/main.cpp index f0de52115..124cd1027 100644 --- a/exercises/30_std_unique_ptr/main.cpp +++ b/exercises/30_std_unique_ptr/main.cpp @@ -53,10 +53,8 @@ int main(int argc, char **argv) { {"fd"}, // TODO: 分析 problems[1] 中资源的生命周期,将记录填入 `std::vector` // NOTICE: 此题结果依赖对象析构逻辑,平台相关,提交时以 CI 实际运行平台为准 - // 解释:第一次 reset 销毁 R1(记录 "ffr"),随后 drop 销毁 R2(记录 "d") - {"ffr", "d", "", "", "", "", "", ""}, - // 解释:序列中先后销毁 R1("r"), R2("d"), R3("r"), R4("d") - {"r", "d", "r", "d", "", "", "", ""}, + {"ffr", "d"}, // problems[1] + {"r", "d", "d"}, // problems[2] }; // ---- 不要修改以下代码 ---- diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index 22e4b12be..4c9d8430c 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -6,39 +6,39 @@ // TODO: 将下列 `?` 替换为正确的值 int main(int argc, char **argv) { - auto shared = std::make_shared(10); // use_count = 1 - std::shared_ptr ptrs[]{shared, shared, shared}; // use_count = 4 (shared + 3) + auto shared = std::make_shared(10); + std::shared_ptr ptrs[]{shared, shared, shared}; std::weak_ptr observer = shared; - ASSERT(observer.use_count() == 4, ""); // 1(shared)+3(ptrs) + ASSERT(observer.use_count() == 4, ""); // shared + ptrs[0] + ptrs[1] + ptrs[2] - ptrs[0].reset(); // -1 - ASSERT(observer.use_count() == 3, ""); + ptrs[0].reset(); + ASSERT(observer.use_count() == 3, ""); // 释放一份 - ptrs[1] = nullptr; // -1 - ASSERT(observer.use_count() == 2, ""); + ptrs[1] = nullptr; + ASSERT(observer.use_count() == 2, ""); // 再释放一份 - ptrs[2] = std::make_shared(*shared); // ptrs[2] 指向新对象,不再共享旧对象 -> -1 - ASSERT(observer.use_count() == 1, ""); + ptrs[2] = std::make_shared(*shared); + ASSERT(observer.use_count() == 1, ""); // ptrs[2] 指向新对象,不再共享旧控制块 - ptrs[0] = shared; // +1 - ptrs[1] = shared; // +1 - ptrs[2] = std::move(shared); // 原 shared 空,ptrs[2] 接管 -> +1 - ASSERT(observer.use_count() == 4, ""); // use_count 回到 4 + ptrs[0] = shared; // +1 + ptrs[1] = shared; // +1 + ptrs[2] = std::move(shared); // 转移 shared 到 ptrs[2],总拥有者数不变 + ASSERT(observer.use_count() == 3, ""); - std::ignore = std::move(ptrs[0]); // 移走 ptrs[0],旧的 -1 - ptrs[1] = std::move(ptrs[1]); // 自己 move 给自己,不变 - ptrs[1] = std::move(ptrs[2]); // ptrs[1] 原来的释放(-1),再接管 ptrs[2](+1),总数不变 - ASSERT(observer.use_count() == 3, ""); // 现在只有 ptrs[1]、以及之前的 observer/weak,不算,实际有 3 个 shared_ptr + std::ignore = std::move(ptrs[0]); // 移走并销毁临时,等价于清空 ptrs[0],-1 + ptrs[1] = std::move(ptrs[1]); // 自我移动,无变化 + ptrs[1] = std::move(ptrs[2]); // 先释放自身再接管 ptrs[2],两者合并为一个拥有者 + ASSERT(observer.use_count() == 1, ""); - shared = observer.lock(); // 再拿一份强引用 -> +1 - ASSERT(observer.use_count() == 4, ""); + shared = observer.lock(); // 再获得一份强引用 + ASSERT(observer.use_count() == 2, ""); - shared = nullptr; // -1 - for (auto &ptr : ptrs) ptr = nullptr; // 把剩余的 ptrs 清掉 -> -2 + shared = nullptr; + for (auto &ptr : ptrs) ptr = nullptr; // 清空数组里剩余的那一份 ASSERT(observer.use_count() == 0, ""); - shared = observer.lock(); // 对象已析构,lock 得到 nullptr + shared = observer.lock(); // 对象已销毁,lock 得到空 ASSERT(observer.use_count() == 0, ""); return 0; From 67861c90d55e638ed71fae87e97f54495a30ddb1 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sun, 17 Aug 2025 10:14:12 +0800 Subject: [PATCH 14/17] Update all changes in submodule learning-cxx --- exercises/30_std_unique_ptr/main.cpp | 4 ++-- exercises/31_std_shared_ptr/main.cpp | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/exercises/30_std_unique_ptr/main.cpp b/exercises/30_std_unique_ptr/main.cpp index 124cd1027..cc0e76fd2 100644 --- a/exercises/30_std_unique_ptr/main.cpp +++ b/exercises/30_std_unique_ptr/main.cpp @@ -53,8 +53,8 @@ int main(int argc, char **argv) { {"fd"}, // TODO: 分析 problems[1] 中资源的生命周期,将记录填入 `std::vector` // NOTICE: 此题结果依赖对象析构逻辑,平台相关,提交时以 CI 实际运行平台为准 - {"ffr", "d"}, // problems[1] - {"r", "d", "d"}, // problems[2] + {"ffr", "d"}, + {"r", "d", "d"}, }; // ---- 不要修改以下代码 ---- diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index 4c9d8430c..f463854eb 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -10,35 +10,35 @@ int main(int argc, char **argv) { std::shared_ptr ptrs[]{shared, shared, shared}; std::weak_ptr observer = shared; - ASSERT(observer.use_count() == 4, ""); // shared + ptrs[0] + ptrs[1] + ptrs[2] + ASSERT(observer.use_count() == 4, ""); // shared + 3 个数组元素 ptrs[0].reset(); - ASSERT(observer.use_count() == 3, ""); // 释放一份 + ASSERT(observer.use_count() == 3, ""); ptrs[1] = nullptr; - ASSERT(observer.use_count() == 2, ""); // 再释放一份 + ASSERT(observer.use_count() == 2, ""); - ptrs[2] = std::make_shared(*shared); - ASSERT(observer.use_count() == 1, ""); // ptrs[2] 指向新对象,不再共享旧控制块 + ptrs[2] = std::make_shared(*shared); // ptrs[2] 改指向新对象,旧控制块 -1 + ASSERT(observer.use_count() == 1, ""); - ptrs[0] = shared; // +1 - ptrs[1] = shared; // +1 - ptrs[2] = std::move(shared); // 转移 shared 到 ptrs[2],总拥有者数不变 + ptrs[0] = shared; // +1 → 2 + ptrs[1] = shared; // +1 → 3 + ptrs[2] = std::move(shared); // 接管 shared(shared 清空),总数仍 3 ASSERT(observer.use_count() == 3, ""); - std::ignore = std::move(ptrs[0]); // 移走并销毁临时,等价于清空 ptrs[0],-1 - ptrs[1] = std::move(ptrs[1]); // 自我移动,无变化 - ptrs[1] = std::move(ptrs[2]); // 先释放自身再接管 ptrs[2],两者合并为一个拥有者 + std::ignore = std::move(ptrs[0]); // 清空 ptrs[0] → 2 + ptrs[1] = std::move(ptrs[1]); // 自我移动,无变化 → 2 + ptrs[1] = std::move(ptrs[2]); // 合并所有权:先释放自身(-1)再接管(+0),最终只剩 1 ASSERT(observer.use_count() == 1, ""); - shared = observer.lock(); // 再获得一份强引用 + shared = observer.lock(); // 再拿一份强引用 → 2 ASSERT(observer.use_count() == 2, ""); shared = nullptr; - for (auto &ptr : ptrs) ptr = nullptr; // 清空数组里剩余的那一份 + for (auto &ptr : ptrs) ptr = nullptr; // 把最后那份也清了 → 0 ASSERT(observer.use_count() == 0, ""); - shared = observer.lock(); // 对象已销毁,lock 得到空 + shared = observer.lock(); // 对象已析构,拿不到 → 0 ASSERT(observer.use_count() == 0, ""); return 0; From d8f6a6a83484915bec182f0bd8f4cfc371cdf3a4 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sun, 17 Aug 2025 10:28:03 +0800 Subject: [PATCH 15/17] Update all changes in submodule learning-cxx --- exercises/30_std_unique_ptr/main.cpp | 4 ++-- exercises/31_std_shared_ptr/main.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/30_std_unique_ptr/main.cpp b/exercises/30_std_unique_ptr/main.cpp index cc0e76fd2..9f55086aa 100644 --- a/exercises/30_std_unique_ptr/main.cpp +++ b/exercises/30_std_unique_ptr/main.cpp @@ -53,8 +53,8 @@ int main(int argc, char **argv) { {"fd"}, // TODO: 分析 problems[1] 中资源的生命周期,将记录填入 `std::vector` // NOTICE: 此题结果依赖对象析构逻辑,平台相关,提交时以 CI 实际运行平台为准 - {"ffr", "d"}, - {"r", "d", "d"}, + {"d", "ffr"}, + {"d", "r", "d"}, }; // ---- 不要修改以下代码 ---- diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index f463854eb..99c540e19 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -29,10 +29,10 @@ int main(int argc, char **argv) { std::ignore = std::move(ptrs[0]); // 清空 ptrs[0] → 2 ptrs[1] = std::move(ptrs[1]); // 自我移动,无变化 → 2 ptrs[1] = std::move(ptrs[2]); // 合并所有权:先释放自身(-1)再接管(+0),最终只剩 1 - ASSERT(observer.use_count() == 1, ""); + ASSERT(observer.use_count() == 2, ""); shared = observer.lock(); // 再拿一份强引用 → 2 - ASSERT(observer.use_count() == 2, ""); + ASSERT(observer.use_count() == 3, ""); shared = nullptr; for (auto &ptr : ptrs) ptr = nullptr; // 把最后那份也清了 → 0 From d0e70c03305d000e19790faf940d33b4bfa7b233 Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sun, 17 Aug 2025 10:33:00 +0800 Subject: [PATCH 16/17] Update all changes in submodule learning-cxx --- exercises/31_std_shared_ptr/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index 99c540e19..c34668633 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -32,7 +32,7 @@ int main(int argc, char **argv) { ASSERT(observer.use_count() == 2, ""); shared = observer.lock(); // 再拿一份强引用 → 2 - ASSERT(observer.use_count() == 3, ""); + ASSERT(observer.use_count() == 4, ""); shared = nullptr; for (auto &ptr : ptrs) ptr = nullptr; // 把最后那份也清了 → 0 From fd5aa07b3384d4ab316b77a92b2950df5916f97f Mon Sep 17 00:00:00 2001 From: messi12123 <1528760260@qq.com> Date: Sun, 17 Aug 2025 10:42:52 +0800 Subject: [PATCH 17/17] Update all changes in submodule learning-cxx --- exercises/30_std_unique_ptr/main.cpp | 9 ++++----- exercises/31_std_shared_ptr/main.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/exercises/30_std_unique_ptr/main.cpp b/exercises/30_std_unique_ptr/main.cpp index 9f55086aa..e07531b27 100644 --- a/exercises/30_std_unique_ptr/main.cpp +++ b/exercises/30_std_unique_ptr/main.cpp @@ -51,12 +51,11 @@ int main(int argc, char **argv) { std::vector answers[]{ {"fd"}, - // TODO: 分析 problems[1] 中资源的生命周期,将记录填入 `std::vector` - // NOTICE: 此题结果依赖对象析构逻辑,平台相关,提交时以 CI 实际运行平台为准 - {"d", "ffr"}, - {"d", "r", "d"}, + // 分析 problems[1] 中资源的生命周期 + {"f", "fd"}, + // 分析 problems[2] 中资源的生命周期 + {"d", "d", "rd"}, }; - // ---- 不要修改以下代码 ---- for (auto i = 0; i < 3; ++i) { diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index c34668633..99c540e19 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -32,7 +32,7 @@ int main(int argc, char **argv) { ASSERT(observer.use_count() == 2, ""); shared = observer.lock(); // 再拿一份强引用 → 2 - ASSERT(observer.use_count() == 4, ""); + ASSERT(observer.use_count() == 3, ""); shared = nullptr; for (auto &ptr : ptrs) ptr = nullptr; // 把最后那份也清了 → 0