📜  C ++ |其他C ++ |问题3(1)

📅  最后修改于: 2023-12-03 14:59:36.557000             🧑  作者: Mango

C++ | 其他C++ | 问题3

问题描述

在C++中,我们经常需要使用指针来动态分配内存。然而,在手动分配内存时,必须在不再需要时显式地释放分配的内存以避免内存泄漏。在某些情况下,指针可能在程序中多次出现,这可能导致问题,尤其是在释放内存时。为了避免这些问题,C++ 11引入了智能指针。智能指针是一种RAII(Resource Acquisition Is Initialization,资源获取即初始化)技术,它自动在不再需要时释放分配的内存。那么,什么是智能指针?如何使用智能指针?有哪些类型的智能指针?这都是我们需要了解的问题。

智能指针概述

智能指针是一种封装了指针的对象,它可以自动释放分配的内存资源,从而避免内存泄漏。智能指针与普通指针的不同之处在于,在对象的析构函数中释放所引用的内存资源,这使得我们不再需要手动释放内存。智能指针使用起来也非常简单,只需要像普通指针一样使用即可。智能指针的语法如下:

std::unique_ptr<T>
std::shared_ptr<T>
std::weak_ptr<T>
unique_ptr

unique_ptr是一种独占所有权的智能指针,它保证指向的对象在使用完毕后会自动被销毁。unique_ptr不能被复制,但它可以被移动,因此可以将所有权从一个unique_ptr转移到另一个unique_ptr。示例代码如下:

#include <memory>
#include <iostream>
 
int main() {
   
    // 创建一个unique_ptr对象,使用make_unique函数分配动态内存并返回unique_ptr对象
    std::unique_ptr<int> ptr1 = std::make_unique<int>(10);
    
    // 输出指针值和对象值
    std::cout << "ptr1 pointer: " << ptr1.get() << "\n";
    std::cout << "ptr1 value: " << *ptr1.get() << "\n";
 
    // unique_ptr不能进行复制,但可以进行移动
    std::unique_ptr<int> ptr2 = std::move(ptr1);
    std::cout << "ptr2 pointer: " << ptr2.get() << "\n";
    std::cout << "ptr2 value: " << *ptr2.get() << "\n";
 
    return 0;
}
shared_ptr

shared_ptr是一种共享所有权的智能指针,它可以被多个指针共享,指向的对象会在所有相关的智能指针对象都被销毁后自动释放。shared_ptr可以被复制和移动,它使用引用计数机制跟踪使用它的指针数量来确定何时删除对象。示例代码如下:

#include <memory>
#include <iostream>
 
int main() {

    // 创建一个shared_ptr对象,使用make_shared函数分配动态内存并返回shared_ptr对象
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10);

    // 输出指针值和对象值
    std::cout << "ptr1 pointer: " << ptr1.get() << "\n";
    std::cout << "ptr1 value: " << *ptr1.get() << "\n";

    // 复制shared_ptr
    std::shared_ptr<int> ptr2 = ptr1;
    std::cout << "ptr2 pointer: " << ptr2.get() << "\n";
    std::cout << "ptr2 value: " << *ptr2.get() << "\n";

    // 输出引用计数
    std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";

    // 重置指针
    ptr1.reset();
    std::cout << "ptr1 reset\n";

    // 输出引用计数
    std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";
   
    return 0;
}
weak_ptr

weak_ptr是一种不掌握内存的智能指针,它指向一个shared_ptr管理的对象,它允许我们共享指向该对象的引用,但它本身不会增加引用计数,当所有shared_ptr被删除后,weak_ptr就自动变成空指针。示例代码如下:

#include <memory>
#include <iostream>
 
int main() {

    // 创建一个shared_ptr对象,使用make_shared函数分配动态内存并返回shared_ptr对象
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10);

    // 使用weak_ptr创建一个引用
    std::weak_ptr<int> ptr2 = ptr1;

    // 输出引用计数
    std::cout << "ptr1 use count: " << ptr1.use_count() << "\n";
    std::cout << "ptr2 use count: " << ptr2.use_count() << "\n";

    // 检查是否已被删除
    if(std::shared_ptr<int> p = ptr2.lock()) {
        std::cout << "ptr2 value: " << *p << "\n";
    }
    else {
        std::cout << "object has been deleted\n";
    }

    // 删除shared_ptr对象
    ptr1.reset();
    std::cout << "ptr1 reset\n";

    // 检查是否已被删除
    if(std::shared_ptr<int> p = ptr2.lock()) {
        std::cout << "ptr2 value: " << *p << "\n";
    }
    else {
        std::cout << "object has been deleted\n";
    }

    return 0;
}
总结

总之,智能指针是一种非常有用的工具,可以避免指针操作中的大多数错误和问题。C++11中的三种智能指针,即unique_ptr、shared_ptr和weak_ptr,各具特点,应根据情况选择合适的智能指针。在程序中使用智能指针可以大大简化代码,减少内存泄漏的可能性,并提高程序的可读性和可维护性。