程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

C++动态指针与智能指针

balukai 2025-03-12 12:18:48 文章精选 112 ℃

在 C++ 中,动态指针通常指的是通过动态内存分配创建的指针,以及现代 C++ 中引入的智能指针(Smart Pointers)。动态指针的使用可以帮助开发者更灵活地管理内存,但也需要谨慎处理,以避免内存泄漏和悬空指针等问题。

以下是关于 C++ 动态指针的详细说明:


1. 传统动态指针(Raw Pointers)

在 C++ 中,可以使用 new 和 delete 操作符动态分配和释放内存。这种方式的指针称为“原始指针”(Raw Pointers)。

1.1 动态分配内存

int* ptr = new int;  // 动态分配一个整型内存
*ptr = 10;           // 给动态分配的内存赋值
std::cout << *ptr;   // 输出 10
delete ptr;          // 释放内存

1.2 动态分配数组

int* arr = new int[5]; // 动态分配一个包含 5 个整数的数组
for (int i = 0; i < 5; i++) {
    arr[i] = i + 1;    // 初始化数组
}
delete[] arr;          // 释放数组内存

1.3 注意事项

  • 内存泄漏:如果忘记调用 delete,会导致内存泄漏。
  • 悬空指针:释放内存后,指针仍然指向原来的地址,访问它会导致未定义行为。
  • 重复释放:对同一块内存多次调用 delete 会导致程序崩溃。

2. 智能指针(Smart Pointers)

为了解决传统动态指针的问题,C++11 引入了智能指针。智能指针是封装了原始指针的类模板,能够自动管理内存的生命周期,避免内存泄漏和悬空指针。

2.1std::unique_ptr

std::unique_ptr 是一种独占所有权的智能指针,确保同一时间只有一个指针可以管理内存。

使用方法

#include 

std::unique_ptr ptr = std::make_unique(10); // 动态分配内存并初始化
std::cout << *ptr; // 输出 10
// 不需要手动调用 delete,内存会自动释放

特点

  • 不能复制,只能通过 std::move 转移所有权。
  • 适合管理独占资源。

2.2std::shared_ptr

std::shared_ptr 是一种共享所有权的智能指针,通过引用计数管理内存。当引用计数为 0 时,内存会自动释放。

使用方法

#include 

std::shared_ptr ptr1 = std::make_shared(10); // 动态分配内存并初始化
std::shared_ptr ptr2 = ptr1; // 共享所有权
std::cout << *ptr1 << " " << *ptr2; // 输出 10 10
// 不需要手动调用 delete,内存会自动释放

特点

  • 可以复制,引用计数会增加。
  • 适合管理共享资源。

2.3std::weak_ptr

std::weak_ptr 是一种弱引用的智能指针,用于解决 std::shared_ptr 的循环引用问题。它不增加引用计数。

使用方法

#include 

std::shared_ptr sharedPtr = std::make_shared(10);
std::weak_ptr weakPtr = sharedPtr;

if (auto temp = weakPtr.lock()) { // 尝试获取 shared_ptr
    std::cout << *temp; // 输出 10
} else {
    std::cout << "对象已释放";
}

特点

  • 不增加引用计数,不会影响内存的释放。
  • 需要调用 lock() 方法获取 std::shared_ptr。

3. 智能指针的使用场景

3.1 资源管理

智能指针可以自动管理动态分配的内存、文件句柄、网络连接等资源,避免资源泄漏。

3.2 避免悬空指针

智能指针在释放内存后会自动将指针置空,避免悬空指针问题。

3.3 解决循环引用

通过 std::weak_ptr 可以解决 std::shared_ptr 的循环引用问题。


4. 示例代码

以下是一个综合使用智能指针的示例:

#include 
#include 

class MyClass {
public:
    MyClass() { std::cout << "MyClass 创建\n"; }
    ~MyClass() { std::cout << "MyClass 销毁\n"; }
    void doSomething() { std::cout << "Doing something!\n"; }
};

int main() {
    // 使用 unique_ptr
    std::unique_ptr uniquePtr = std::make_unique();
    uniquePtr->doSomething();

    // 使用 shared_ptr
    std::shared_ptr sharedPtr1 = std::make_shared();
    std::shared_ptr sharedPtr2 = sharedPtr1;
    sharedPtr1->doSomething();

    // 使用 weak_ptr
    std::weak_ptr weakPtr = sharedPtr1;
    if (auto temp = weakPtr.lock()) {
        temp->doSomething();
    }

    return 0;
}

5. 总结

  • 原始指针:需要手动管理内存,容易出错。
  • 智能指针:自动管理内存,推荐使用。
    • std::unique_ptr:独占所有权,适合管理独占资源。
    • std::shared_ptr:共享所有权,适合管理共享资源。
    • std::weak_ptr:弱引用,解决循环引用问题。

在现代 C++ 开发中,尽量使用智能指针来管理动态内存,以提高代码的安全性和可维护性。

最近发表
标签列表