编译运行:clang++ -std=c++26 -Wall -Wextra -pthread 测试_第08章_指针与内存.cpp -o t && ./t(需先 cd 测试/)
// 第8章测试:指针与内存(智能指针 / RAII / 引用)
#include <print>
#include <memory>
#include <string>
#include <vector>
int failures = 0;
#define CHECK(expr) \
do { \
if (!(expr)) { \
++failures; \
std::println("FAIL 第{}行: {}", __LINE__, #expr); \
} \
} while (0)
struct Counter {
static inline int alive = 0; // C++17 inline 变量
Counter() { ++alive; }
~Counter() { --alive; }
};
// RAII 类演示:析构自动还资源
class ScopedGuard {
public:
explicit ScopedGuard(const std::string& name) : name_(name) {
std::println("进入作用域:{}", name_);
++active_;
}
~ScopedGuard() {
std::println("离开作用域:{}", name_);
--active_;
}
static inline int active_ = 0;
private:
std::string name_;
};
int main() {
// 8.1 指针基础
int x = 10;
int* p = &x;
*p = 20;
CHECK(x == 20);
CHECK(p != nullptr);
int* np = nullptr;
CHECK(np == nullptr);
// 8.4 智能指针:unique_ptr
std::unique_ptr<int> u = std::make_unique<int>(42);
CHECK(*u == 42);
std::unique_ptr<Counter> cu = std::make_unique<Counter>();
CHECK(Counter::alive == 1);
cu.reset(); // 手动释放
CHECK(Counter::alive == 0);
// 独占性验证
std::unique_ptr<int> u2 = std::make_unique<int>(1);
std::unique_ptr<int> u3 = std::move(u2); // 所有权转移
CHECK(u2 == nullptr);
CHECK(*u3 == 1);
// shared_ptr 引用计数
std::shared_ptr<Counter> s1 = std::make_shared<Counter>();
CHECK(s1.use_count() == 1);
{
std::shared_ptr<Counter> s2 = s1;
CHECK(s1.use_count() == 2);
CHECK(Counter::alive == 1); // 同一对象只构造一次
}
CHECK(s1.use_count() == 1); // s2 销毁,计数回 1
s1.reset();
CHECK(Counter::alive == 0); // 计数归零,真正释放
// weak_ptr:不增加计数
std::shared_ptr<int> sp = std::make_shared<int>(7);
std::weak_ptr<int> wp = sp;
CHECK(sp.use_count() == 1); // weak 不计数
CHECK(wp.expired() == false);
if (auto locked = wp.lock()) CHECK(*locked == 7);
sp.reset();
CHECK(wp.expired()); // 对象没了
// 循环引用演示(weak 破环):
struct Node {
std::string name;
std::shared_ptr<Node> next;
std::weak_ptr<Node> parent; // 用 weak 避免环
};
auto n1 = std::make_shared<Node>();
auto n2 = std::make_shared<Node>();
n1->next = n2;
n2->parent = n1; // weak 不形成环
// 8.5 RAII:作用域结束自动析构
CHECK(ScopedGuard::active_ == 0);
{
ScopedGuard g("测试块");
CHECK(ScopedGuard::active_ == 1);
} // 这里自动析构
CHECK(ScopedGuard::active_ == 0);
// 8.6 引用:不能为空、不能换绑
int a = 1, b = 2;
int& r = a;
r = b; // 赋值不是换绑!
CHECK(a == 2 && b == 2); // a 被赋成 2,r 仍是 a 的别名
CHECK(&r == &a);
// 智能指针管理容器
auto vec = std::make_unique<std::vector<int>>();
vec->push_back(1);
vec->push_back(2);
CHECK(vec->size() == 2);
if (failures == 0) std::println("全部通过");
return failures;
}