2026/4/18 7:38:29
网站建设
项目流程
建设监理继续教育网站,怎么看网站建设时间,租车网站模板,网站搭建外贸智能指针1、智能指针本身#xff1a;智能指针是一个类模板的实例#xff0c;通常作为局部变量存在于栈区#xff08;Stack#xff09;。当函数返回或者局部变量超出其作用域时#xff0c;栈区的内存会被自动释放。2、智能指针管理的对象#xff1a;智能指针通常用来管理在…智能指针1、智能指针本身智能指针是一个类模板的实例通常作为局部变量存在于栈区Stack。当函数返回或者局部变量超出其作用域时栈区的内存会被自动释放。2、智能指针管理的对象智能指针通常用来管理在堆区Heap上分配的内存。这是通过调用如new操作符来完成的。堆区的内存会一直存在直到显式地释放它使用delete操作符或者当程序结束时才会被系统回收。C对于普通的new或者malloc分配空间需要及时的释放空间否则容易造成内存泄漏导致堆区空间不足。但是随着代码量的增多很容易忘记释放空间于是智能指针应运而生。智能指针会自动释放。省去手动管理内存。在智能指针中会存在一个计数器计数器的大小等于指向对象的智能指针的数量当计数为0时则释放指针。智能指针在memory头文件中。std::unique_ptr它实现了对对象的独占所有权语义。这意味着一个unique_ptr在任何时候都指向一个对象而且这个对象只能由一个unique_ptr拥有。当unique_ptr被销毁例如离开其作用域时它所指向的对象也会被自动删除。std::shared_ptr它实现了对象的共享所有权语义。多个shared_ptr可以指向同一个对象并且每个shared_ptr持有一个引用计数。当最后一个指向某个对象的shared_ptr被销毁或重置时该对象才会被删除。std::weak_ptr它是对shared_ptr所管理对象的一个非拥有性引用它指向一个由shared_ptr管理的对象但并不影响对象的生命周期。也就是说它不会增加所指向对象的引用计数。当最后一个指向对象的shared_ptr被销毁时无论是否还有weak_ptr指向该对象对象都会被删除。weak_ptr主要用于解决shared_ptr可能导致的循环引用问题。在这部分利用率局部变量的特性C的局部变量存在栈中当变量的生命周期结束后那栈会自动释放空间。而智能指针同样为局部变量存在栈中。//很简单的一个类帮助解释智能指针 class Ball { public: Ball() { cout creat Ball endl; } ~Ball() { cout delete Ball endl; } void bounce() { cout A Ball jumps endl; } };1、智能指针类型智能指针类型shared_ptr共享指针多个共享指针可以指向同一个对象weak_ptr该指针是对象的一个非拥有性引用指向一个shared_ptr主要用来避免shared_ptr环形依赖unique_ptr该指针独占对象的所有权每个对象只能有一个该指针2、shared_ptr智能指针内部有一个计数器当赋值给别的智能指针或者函数传参拷贝到另一个shared_ptr计数器就会加1当函数执行完毕智能指针对象就被析构了此时计数器就会减1直到计数器变为0说明没人在用这个对象了就执行delete把它释放掉。1、创建方式//创建方式1 shared_ptrint p; p make_sharedint(100);//此为推荐方式 //创建方式2 shared_ptrint p2{new int(100)}; //使用方式和普通指针一样 shared_ptrint p3 p; cout *p endl; *p3 321; cout *p3 endl;2、成员函数1、use_count()得到当前有多少个指针指向该对象class Ball {}; shared_ptrBall ball make_sharedBall(); cout ball.use_count endl;//ball.use_count()展示当前有多少个指针指向这个物体值为1 shared_ptrBall ball2 make_sharedBall(); cout ball.use_count() ball2.use_count() endl;//值为1 2 shared_ptrBall ball3 make_sharedBall(); cout ball.use_count() ball2.use_count() cout ball3.count() endl;//值为1 2 3 ball.reset();//重置智能指针 ball2.reset(); ball3.reset();//重置智能指针三个指针都释放后ball会自动销毁避免内存泄漏也可以reset(new Ball)指向一个新的对象2、get()获得裸指针Ball* rp p.get();rp指向当前资源但若裸指针与共享指针都指向这块资源若全部共享指针释放后这块资源也会被释放裸指针变成未定义的所以尽可能避免裸指针和共享指针同时使用。3、weak_ptr()3.1环形依赖循环引用是指两个或多个对象通过智能指针相互引用导致它们的计数永远不为零从而引发内存泄漏。循环引用会在以下情况下产生当两个或多个对象相互持有对方的智能指针通常是shared_ptr时它们之间的引用计数将永远无法降到零因为每个对象都在等待其他对象被销毁以释放自己。这种情况下即使这些对象不再被程序的其他部分使用它们所占用的内存也无法被释放从而导致内存泄漏。通过使用weak_ptr代替其中一个或多个shared_ptr可以打破这种循环引用确保对象在不再需要时能够被正确销毁。以下代码执行完后不会输出析构函数cout内容说明这两个对象没有被删除这是因为智能指针的计数没有变成0但只要将Teacher类中的成员变量改为weak_ptrSchool school;即可避免环形依赖。struct School; struct Teacher { string name; int age; shared_ptrSchool school;//改为weak_ptrSchool school;即可避免环形依赖 ~Teacher() { cout Teacher Destructed. endl; } }; struct School { string name; shared_ptrTeacher principle; ~School() { cout School Destructed. endl; } }; void test_range_conflict() { auto principle make_sharedTeacher(); auto university make_sharedSchool(); principle-school university; university-principle principle; }3.2weak_ptrweak_ptr本身依赖shared_ptr存在存储一个资源的引用但不能修改只能告知资源是否存在。cpp.lock()返回shared_ptr地址指针若对象已被释放则返回nullptr。void test_weak_ptr() { weak_ptrint wp; shared_ptrint sp make_sharedint(100); wp sp; auto resource wp.lock();//wp.lock()返回指针若被释放则返回nullptr if(resource){ cout Number is *resource endl; } else { cout wp is expired endl; } }4、unique_ptrunique_ptr是独享的不可以两个unique_ptr同时指向同一份资源由于独占资源控制权所以不支持普通拷贝但可以转移控制权4.1get()release()和move()创建unique_ptr指针unique_ptrBall ball make_uniqueBall();Ball *p ball.get();//获得裸指针ball.reset(new Ball());//重新指向另一个Ball对象Ball *ball2 ball.release();//unique_ptr与资源解绑release返回资源的裸指针同时将unique_ptr设置为nullptr但解绑后需要用delete释放 delete ball2; ball nullptr;//赋值为裸指针也会释放所对应的资源4.2转移控制权unique_ptrint up1 make_uniqueint(100); unique_ptrint up2(up1.release());//方式1转移控制权 unique_ptrint up3 std::move(up1);//方式2转移控制权4.3在函数间传递unique_ptr4.3.1只需要value1.方式1//1只访问内容引用只访问资源 void pass_up1(int value) { cout value endl; } void test_pass_up1() { auto up make_uniqueint(123); pass_up1(*up); }2.方式2//2传递裸指针避免unique_ptr的传递同样只能访问unique_ptr指向的资源 void pass_up2(int *p) { cout *p endl; } void test_pass_up2() { auto up make_uniqueint(123); pass_up2(up.get()); }4.3.2传递unique_ptr实质在做转移控制权1.方式1//3改变unique_ptr本身使用引用方式 void pass_up3(unique_ptrint up) { cout *up endl; up.reset(); } void test_pass_up3() { auto up make_uniqueint(123); pass_up3(up); if (up nullptr) cout up is upset endl; }2.方式2//4改变unique_ptr本身使用move转移控制权 void pass_up4(unique_ptrint up) { cout *up endl; up.reset(); } void test_pass_up4() { auto up make_uniqueint(123); pass_up4(std::move(up)); if (up nullptr) cout up is upset endl; }4.4作为函数返回值作为函数返回值可以直接写return up;或者return(move(up));前者不用写up是因为编译器智能识别返回类型使用move constructor//5unique_ptr可以被作为函数返回值 unique_ptrint return_uptr(int value) { unique_ptrint up make_uniqueint(value); rturn up; } void test_return_uptr() { unique_ptrint up return_uptr(321); cout *up endl; }