C++ 智能指针

智能指针概述

是什么:

智能指针是C++中用来管理动态内存的一种机制。它通过对指针对象进行封装,使得在特定的作49·47用域内自动管理内存的分配和释放。

解决的问题:

智能指针的主要用途是解决C++中常见的内存泄漏和空悬指针问题。它提供了一种方便而安全地使用动态分配对象的方法。

分类:

在C++中,有三种智能指针类型:std::shared_ptr、std::unique_ptr和std::weak_ptr。

std::shared_ptr:是一种共享所有权的智能指针。它可以多个指针同时拥有同一个对象,对象只有在最后一个拥有者释放时才会被销毁。这种指针可以通过std::make_shared函数来创建,也可以使用new关键字来创建。

std::unique_ptr:是一种独占所有权的智能指针。只能有一个unique_ptr指向某个对象。当unique_ptr销毁时,其所指向的对象也会被自动删除。这种指针可以使用new关键字来创建,也可以通过std::make_unique函数来创建

std::weak_ptr:不拥有对象的所有权,只是对shared_ptr的一个引用。它可以用来检测对象是否已被删除,并避免循环引用。

智能指针用法:

新建一个Pointers类来举例说明,类定义如下:

#include

class Pointers {
	public:
		Pointers()=default;
        Pointers(std::string name):name(name){
	        std::cout << "Pointers is constructor:" <name = name;
		}
		void setSName(std::shared_ptr c) {
			w_ptr_p= c;
		}

private:
	std::string name{"First"};   //	std::string name = { "First" };
	std::weak_ptr w_ptr_p;
};

创建方法(有三种,不包括weak_ptr):


	/*智能指针第一种创建方法*/
	Pointers* p = new Pointers("A");
	std::unique_ptru_c_p{ p };
	p = nullptr;


	/*智能指针第二种创建方法*/
	std::unique_ptru_c_p1(new Pointers("B"));   //隐式创建类


	/*智能指针第三中创建方法*/
	std::unique_ptru_c_p2 = std::make_unique();

reset()函数:

        该方法用于释放智能指针所指向的资源。当调用 reset 方法时,智能指针会将其内部的计数器减一,如果计数器减至零,则会自动释放其所指向的资源。

unique_ptr指针用法:

move()函数:
        std::unique_ptr不能复制,只能move:

      这个函数用于将 unique_ptr 的所有权转移给另一个 unique_ptr。当一个 unique_ptr 调用 move() 函数后,它就会变成一个空指针,而所有权则转移给了另一个 unique_ptr

void uniq_ptr_pass_value(std::unique_ptr ptr) {
	ptr->setName("value");
	std::cout << "通过move传递,原始智能指针失效:" << ptr->getName() << std::endl;
}

int maint(){
	std::unique_ptr pt = std::make_unique("pt");
	uniq_ptr_pass_value(move(pt));

    uniq_ptr_pass_value(std::make_unique());        //相当于调用了move


    pt->->info();   //报错,  通过move传递后,pt变成空指针
}



       通过move(),将unique_ptr转换为shared_ptr :
	unique_ptr c_p = make_unique("yy");
	shared_ptrs_p = move(c_p);
unique_ptr与函数:

        因为unique_ptr不能复制, 所以除了move(),还可以引用的方式作为函数参数。此时需要注意有const和没有const的情况。

void uniq_ptr_ref(std::unique_ptr& ptr) {
	ptr.reset();        //没有加const时可以调用reset();
}
void uniq_ptr_refconst(const std::unique_ptr& ptr) {
	ptr.reset();        //有const限定符时会报错,
}

int main(){
    
    std::unique_ptr c_p_1 =std::make_unique("aa");
    uniq_ptr_ref(c_p_1);        //此函数会释放c_p_1指向的资源并把指针c_p_1置为空
    c_p_1->info();              //报错,c_p_1为空。
    
    std::unique_ptr c_p_2 =std::make_unique("bb");
    uniq_ptr_refconst(c_p_2);
    c_p_2->info();              //正常输出
}

shared_ptr指针用法:

use_count()函数:

    该函数返回指向由 shared_ptr 管理的对象的共享所有权的引用计数。

	shared_ptr c_p_1 = make_shared();
	shared_ptr c_p_2 = c_p_1;
	shared_ptr c_p_3{ c_p_2 };

	cout << "c_p_1 use_count: " << c_p_1.use_count() << endl;    //输出3
	cout << "c_p_2 use_count: " << c_p_2.use_count() << endl;    //输出3
    cout << "c_p_3 use_count: " << c_p_3.use_count() << endl;    //输出3
shared_ptr与函数:
void shared_ptr_value(shared_ptr ptr) {
	cout << "func use_count: " << ptr.use_count() << endl;    
}
void shared_ptr_ref(shared_ptr& ptr) {
	cout << "func use_count: " << ptr.use_count() << endl;
}
void shared_ptr_ref_const(const shared_ptr& ptr) {
	cout << "func use_count: " << ptr.use_count() << endl;
    //ptr.reset();         //这里不能被reset,因为有const限制
}

int main(){
       std::shared_ptr c_p_1=std::make_shared("cc");

        shared_ptr_value(c_p_1);                       //输出2
        std::cout<

weak_ptr:

        weak_ptr创建

        weak_ptr指针不能直接创建,通过指向shared_ptr得到weak_ptr指针。

	shared_ptrs_ptr_p1 = make_shared("ff");
	weak_ptrw_ptr_p1{ s_ptr_p1 };    //得到一个weak_ptr指针

    std::cout<
      lock()函数

        lock() 函数的主要用途是尝试获取对对象的访问权。如果 std::weak_ptr 所指向的对象仍然存在,那么 lock() 函数将返回一个指向该对象的 std::shared_ptr,并且该 std::shared_ptr 的引用计数加一。如果对象不存在,那么 lock() 函数将返回一个空的 std::shared_ptr

	shared_ptrs_ptr_p = make_shared("hh");    
    
    shared_ptrs_ptr_p1(new Pointers("gg"));

    weak_ptrw_ptr_p = s_ptr_p;                           //weak_ptr指向s_ptr_p

    

	s_ptr_p1 = w_ptr_p.lock();                    //如果w_ptr_p指向的对象存在,lock()函数返回有效的std::shared_ptr,并让s_ptr_p1的引用计数器加1,如果不存在就返回空的std::shared_ptr
    if(s_ptr_p1){
        // 对象仍然存在,可以安全地使用它  
            std::cout << s_ptr_p1.use_count()<
shared_ptr死循环问题:

        在使用 std::shared_ptr 时没有正确地管理共享所有权,可能会导致死循环问题。死循环问题通常发生在两个或多个 shared_ptr 对象相互引用时,导致它们之间的引用计数永远不会减少到零,从而导致程序无法正常结束。

#include
#include

class Pointers {
	public:
		Pointers()=default;
        Pointers(std::string name):name(name){
	        std::cout << "Pointers is constructor:" < c) {
			m_sptr= c;
            //m_wptr=c;
		}

private:
	std::string name{"First"};   //	std::string name = { "First" };
	//std::weak_ptr m_wptr;
    std::shared_ptr m_sptr;
};


int main(){

        std::shared_ptr s_ptr_p= std::make_shared("jj");
        std::shared_ptr s_ptr_p1= std::make_shared("kk");
        //创建了两个shared_ptr

        s_ptr_p->setName(s_ptr_p1);        
        s_ptr_p1->setName(s_ptr_p);
        //两个shared_ptr对象相互引用,  此时程序会进入死循环,永远不能释放这两个指针


        //此时,可用weak_ptr指针来避免死循环。把Pointers类的成员变量-shared_ptr换成weak_ptr就可以了
        

}





你可能感兴趣的:(笔记)