C++智能指针与内存管理实践
C智能指针与内存管理实践智能指针是C中自动管理动态内存的关键工具。通过RAII机制智能指针在对象生命周期结束时自动释放内存避免内存泄漏和悬空指针问题。std::unique_ptr提供独占所有权语义确保同一时刻只有一个指针拥有资源。它的开销极小几乎等同于原始指针。#include#include#includeclass Resource {int id_;std::vector data_;public:explicit Resource(int id) : id_(id), data_(1000, id) {std::cout Resource id_ created\n;}~Resource() {std::cout Resource id_ destroyed\n;}void process() {std::cout Processing resource id_ \n;}int id() const { return id_; }};void unique_ptr_basic() {std::unique_ptr ptr1(new Resource(1));ptr1-process();auto ptr2 std::make_unique(2);ptr2-process();std::unique_ptr ptr3 std::move(ptr2);if (!ptr2) {std::cout ptr2 is now null\n;}ptr3-process();}std::unique_ptr的自定义删除器允许管理非内存资源如文件句柄、网络连接等。struct FileDeleter {void operator()(FILE* fp) const {if (fp) {std::cout Closing file\n;fclose(fp);}}};void custom_deleter_example() {std::unique_ptr file(fopen(test.txt, w));if (file) {fprintf(file.get(), Hello from unique_ptr\n);}}templateclass UniquePtr {T* ptr_;void cleanup() {delete ptr_;ptr_ nullptr;}public:explicit UniquePtr(T* p nullptr) : ptr_(p) {}~UniquePtr() {cleanup();}UniquePtr(const UniquePtr) delete;UniquePtr operator(const UniquePtr) delete;UniquePtr(UniquePtr other) noexcept : ptr_(other.ptr_) {other.ptr_ nullptr;}UniquePtr operator(UniquePtr other) noexcept {if (this ! other) {cleanup();ptr_ other.ptr_;other.ptr_ nullptr;}return *this;}T* get() const { return ptr_; }T* release() {T* temp ptr_;ptr_ nullptr;return temp;}void reset(T* p nullptr) {cleanup();ptr_ p;}T operator*() const { return *ptr_; }T* operator-() const { return ptr_; }explicit operator bool() const { return ptr_ ! nullptr; }};std::shared_ptr实现引用计数允许多个指针共享同一资源。当最后一个shared_ptr被销毁时资源才会被释放。void shared_ptr_basic() {std::shared_ptr sp1 std::make_shared(10);std::cout Use count: sp1.use_count() \n;{std::shared_ptr sp2 sp1;std::cout Use count: sp1.use_count() \n;sp2-process();}std::cout Use count after scope: sp1.use_count() \n;}templateclass SharedPtr {T* ptr_;size_t* ref_count_;void release() {if (ref_count_) {--(*ref_count_);if (*ref_count_ 0) {delete ptr_;delete ref_count_;}}}public:explicit SharedPtr(T* p nullptr): ptr_(p), ref_count_(p ? new size_t(1) : nullptr) {}~SharedPtr() {release();}SharedPtr(const SharedPtr other): ptr_(other.ptr_), ref_count_(other.ref_count_) {if (ref_count_) {(*ref_count_);}}SharedPtr operator(const SharedPtr other) {if (this ! other) {release();ptr_ other.ptr_;ref_count_ other.ref_count_;if (ref_count_) {(*ref_count_);}}return *this;}SharedPtr(SharedPtr other) noexcept: ptr_(other.ptr_), ref_count_(other.ref_count_) {other.ptr_ nullptr;other.ref_count_ nullptr;}SharedPtr operator(SharedPtr other) noexcept {if (this ! other) {release();ptr_ other.ptr_;ref_count_ other.ref_count_;other.ptr_ nullptr;other.ref_count_ nullptr;}return *this;}T* get() const { return ptr_; }size_t use_count() const { return ref_count_ ? *ref_count_ : 0; }T operator*() const { return *ptr_; }T* operator-() const { return ptr_; }explicit operator bool() const { return ptr_ ! nullptr; }};std::weak_ptr用于打破循环引用它不增加引用计数但可以检测对象是否仍然存在。class Node {public:int value;std::shared_ptr next;std::weak_ptr prev;explicit Node(int v) : value(v) {std::cout Node value created\n;}~Node() {std::cout Node value destroyed\n;}};void weak_ptr_example() {auto node1 std::make_shared(1);auto node2 std::make_shared(2);node1-next node2;node2-prev node1;if (auto prev node2-prev.lock()) {std::cout Previous node value: prev-value \n;}}智能指针与容器结合使用时可以实现多态容器和资源管理。class Shape {public:virtual ~Shape() default;virtual void draw() const 0;virtual double area() const 0;};class Circle : public Shape {double radius_;public:explicit Circle(double r) : radius_(r) {}void draw() const override {std::cout Drawing circle with radius radius_ \n;}double area() const override {return 3.14159 * radius_ * radius_;}};class Rectangle : public Shape {double width_, height_;public:Rectangle(double w, double h) : width_(w), height_(h) {}void draw() const override {std::cout Drawing rectangle width_ x height_ \n;}double area() const override {return width_ * height_;}};void polymorphic_container() {std::vector shapes;shapes.push_back(std::make_unique(5.0));shapes.push_back(std::make_unique(4.0, 6.0));shapes.push_back(std::make_unique(3.0));double total_area 0;for (const auto shape : shapes) {shape-draw();total_area shape-area();}std::cout Total area: total_area \n;}make_shared相比直接使用shared_ptr构造函数更高效因为它只进行一次内存分配。templatestd::shared_ptr make_shared_impl(Args... args) {return std::shared_ptr(new T(std::forward(args)...));}void allocation_comparison() {auto sp1 std::shared_ptr(new Resource(1));auto sp2 std::make_shared(2);}智能指针的线程安全性需要特别注意。引用计数的修改是线程安全的但对象本身的访问不是。#include#includeclass ThreadSafeCounter {mutable std::mutex mutex_;int value_;public:ThreadSafeCounter() : value_(0) {}void increment() {std::lock_guard lock(mutex_);value_;}int get() const {std::lock_guard lock(mutex_);return value_;}};void thread_safety_example() {auto counter std::make_shared();std::vector threads;for (int i 0; i 10; i) {threads.emplace_back([counter]() {for (int j 0; j 1000; j) {counter-increment();}});}for (auto t : threads) {t.join();}std::cout Final count: counter-get() \n;}enable_shared_from_this允许对象从自身获取shared_ptr这在回调和异步操作中很有用。class AsyncOperation : public std::enable_shared_from_this {int id_;public:explicit AsyncOperation(int id) : id_(id) {}void start() {std::cout Starting operation id_ \n;auto self shared_from_this();std::thread([self]() {std::this_thread::sleep_for(std::chrono::milliseconds(100));std::cout Operation self-id_ completed\n;}).detach();}};void enable_shared_from_this_example() {auto op std::make_shared(1);op-start();std::this_thread::sleep_for(std::chrono::milliseconds(200));}智能指针的性能开销主要来自引用计数的原子操作。在性能关键路径上unique_ptr是更好的选择。#includevoid performance_comparison() {const int iterations 1000000;auto start std::chrono::high_resolution_clock::now();for (int i 0; i iterations; i) {auto ptr std::make_unique(i);volatile int value *ptr;}auto end std::chrono::high_resolution_clock::now();auto duration std::chrono::duration_cast(end - start);std::cout unique_ptr: duration.count() us\n;start std::chrono::high_resolution_clock::now();for (int i 0; i iterations; i) {auto ptr std::make_shared(i);volatile int value *ptr;}end std::chrono::high_resolution_clock::now();duration std::chrono::duration_cast(end - start);std::cout shared_ptr: duration.count() us\n;}智能指针与异常安全紧密相关确保即使在异常发生时资源也能正确释放。void exception_safety() {std::vector resources;try {resources.push_back(std::make_unique(1));resources.push_back(std::make_unique(2));throw std::runtime_error(Error occurred);resources.push_back(std::make_unique(3));} catch (const std::exception e) {std::cout Exception: e.what() \n;std::cout Resources automatically cleaned up\n;}}智能指针是现代C内存管理的基石。正确使用智能指针可以消除大部分内存管理问题使代码更加安全和易于维护。