MST

星途 面试题库

面试题:C++中std::shared_ptr的引用计数机制

请描述C++中std::shared_ptr是如何实现引用计数机制的,并且说明引用计数在什么情况下会增加和减少。
45.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. std::shared_ptr引用计数机制实现
    • std::shared_ptr内部包含两个指针,一个指向对象,另一个指向控制块(control block)。
    • 控制块是一个动态分配的内存块,其中包含引用计数(reference count),可能还包含其他信息,比如弱引用计数(用于std::weak_ptr)等。
    • 当通过std::make_shared或者直接构造std::shared_ptr来指向一个对象时,会分配控制块并初始化引用计数为1。
  2. 引用计数增加情况
    • 拷贝构造:当使用std::shared_ptr的拷贝构造函数创建一个新的std::shared_ptr对象时,如std::shared_ptr<int> ptr1 = std::make_shared<int>(10); std::shared_ptr<int> ptr2(ptr1);,此时新对象ptr2和原对象ptr1指向同一个控制块,控制块中的引用计数加1。
    • 赋值操作:当使用std::shared_ptr的赋值运算符时,如std::shared_ptr<int> ptr1 = std::make_shared<int>(10); std::shared_ptr<int> ptr2; ptr2 = ptr1;ptr2原来指向的对象(如果有)的引用计数减1,ptr1指向对象的引用计数加1。
  3. 引用计数减少情况
    • std::shared_ptr对象析构:当std::shared_ptr对象超出作用域或者被显式释放时,其析构函数会被调用。在析构函数中,控制块中的引用计数减1。如果引用计数减为0,意味着没有其他std::shared_ptr对象指向该对象,那么会释放指向的对象以及控制块的内存。例如:
    {
        std::shared_ptr<int> ptr = std::make_shared<int>(10);
    } // 这里ptr超出作用域,引用计数减1变为0,对象和控制块内存被释放
    
    • 重置(reset)操作:调用std::shared_ptrreset成员函数时,如std::shared_ptr<int> ptr = std::make_shared<int>(10); ptr.reset();,原对象的引用计数减1。如果减为0,同样会释放对象和控制块内存。reset也可以用来指向新的对象,如ptr.reset(new int(20));,此时原对象引用计数减1,新对象引用计数设为1。