网站层级高清免费素材网
网站层级,高清免费素材网,网站工程是干啥的,家具网站首页设计简介 智能指针是一种特殊的指针类型#xff0c;它能够自动管理内存资源#xff0c;避免常见的内存泄漏和多次释放等。在C 11标准中出现了新的智能指针unique_ptr、 shared_ptr、weak_ptr等。 std::unique_ptr 用于管理动态分配的内存资源#xff0c;它提供了自动释放内存的功…简介 智能指针是一种特殊的指针类型它能够自动管理内存资源避免常见的内存泄漏和多次释放等。在C 11标准中出现了新的智能指针unique_ptr、 shared_ptr、weak_ptr等。 std::unique_ptr 用于管理动态分配的内存资源它提供了自动释放内存的功能。与原始指针相比unique_ptr有更高的安全性和易用性。 特点 所有权唯一、自动释放内存、指针语义、禁止拷贝和权限转移、自定义删除器 所有权唯一每个unique_ptr实例拥有对其所指向对象的唯一所有权。这意味着在任何时候只有一个unique_ptr可以指向一个特定的对象。 自动释放内存当unique_ptr超出作用域或被重新赋值时它所管理的内存会自动释放。这样就避免了内存泄漏的问题。 指针语义使用方式与原始指针相似可通过指针操作符-和解引用操作符*来访问所指向对象成员。 禁止拷贝unique_ptr禁止拷贝即不能进行复制构造和赋值操作。这是为了确保独占所有权的特性防止多个指针同时管理同一个对象的内存。 权限转移支持移动构造和移动赋值操作将所有权转移给新的unique_ptr而旧指针则自动释放置空无需进行内存拷贝。 自定义删除器unique_ptr可通过模板参数来指定一个删除器deleter函数对象用于在释放内存时执行额外的清理操作。 缺点 使用裸指针赋值或捕获会很容易非常的乱、导致内存泄露尽量避免智能指针和普通指针的混合。 常见成员函数
常见成员函数:operator* 解引用操作符用于获取 unique_ptr 所指向对象的引用。operator- 箭头操作符用于通过 unique_ptr 访问对象的成员函数或成员变量。get 返回指向所管理对象的裸指针。reset 重置 unique_ptr释放当前所管理的对象并接管新的对象。release 释放对所管理对象的控制权并返回该指针的裸指针。swap 交换两个 unique_ptr 的内容。示例测试 基本操作1
#include iostreamvoid unique_operate1()
{/******************** 创建 ********************/// 创建方式一,初始化后修改值std::unique_ptrint pInt1(new int(10));*pInt1 101;// 创建方式二,初始化后修改值std::unique_ptrint pInt2 std::unique_ptrint(new int(20));*pInt2 102;// 创建方式三,初始化后修改值std::unique_ptrint pInt3 std::make_uniqueint(30);*pInt3 103;// 创建多个int指针对象,初始化后修改值std::unique_ptrint[] pIntArray(new int[5]{ 10,20,30,40,50 });pIntArray[0] 1;pIntArray[1] 2;pIntArray[2] 3;pIntArray[3] 4;pIntArray[4] 5;/*********************************************//******************** 输出地址及值 ********************/std::cout pInt1 *pInt1 | pInt1.get() *(pInt1.get()) std::endl;std::cout pInt1 *pInt1 | pInt1.get() *(pInt1.get()) std::endl;std::cout pInt1 *pInt1 | pInt1.get() *(pInt1.get()) std::endl;/*输出为:000002110F242540 101 | 000002110F242540 101000002110F242540 101 | 000002110F242540 101000002110F242540 101 | 000002110F242540 101*//*********************************************//******************** 权限转移 ********************/std::cout pInt1 *pInt1 std::endl;//std::unique_ptrint P1 pInt1; // 错误操作std::unique_ptrint P1 std::move(pInt1); // 正确操作。此时P1接收了pInt1的地址和值,而pInt1则被置空std::cout P1 *P1 std::endl;/*注意:pInt1由于被置空,此时无法使用否则出现异常。输出为:000002303C431670 101000002303C431670 101*//*********************************************/
}int main()
{// 基本操作1unique_operate1();return 0;
}基本操作2
#include iostreamclass Operate2
{
public:Operate2(){std::cout call Operate2() \t this std::endl;}Operate2(const Operate2 ){std::cout call Operate2(const Operate2 ) \t this std::endl;}~Operate2(){std::cout call ~Operate2() \t this std::endl;}Operate2* operator (int v){std::cout call operator \t this std::endl;Operate2 *tmp new Operate2;tmp-value value v;return tmp;}// 设置value值void setValue(const int v){ value v; }// 获取value值int getValue()const { return value; }private:int value 10;
};void unique_operate2()
{// 进入一次Operate2构造(ptr1)std::unique_ptrOperate2 ptr1 std::make_uniqueOperate2();/******************** 成员操作 ********************/// 测试std::cout print ptr1 ptr add: ptr1 std::endl std::endl;// 测试 -std::cout print ptr2 - value is: ptr1-getValue() std::endl;ptr1-setValue(20);std::cout print ptr2 - value is: ptr1-getValue() std::endl std::endl;// 测试 get :返回指向所管理对象的裸指针Operate2 *tOperate2Ptr ptr1.get();std::cout tOperate2Ptr - value is: ptr1-getValue() std::endl std::endl;/*测试 reset :该方法可让unique_ptr解除对原始内存管理,也可初始化一个独占的智能指针reset() 解除对原始内存的管理reset(new xxx()) 重新指定智能指针管理的原始内存*/ptr1.reset(new Operate2()); // 新创建的进入一次构造,然后之前的对象进入一次析构std::cout new print ptr2 - value is: ptr1-getValue() std::endl std::endl;// 测试 release :释放对所管理对象的控制权,并返回该指针的裸指针Operate2 *ttOperate2Ptr ptr1.release(); // ptr1被置空if (ttOperate2Ptr) { delete ttOperate2Ptr; }ttOperate2Ptr nullptr;std::cout std::endl;// 测试 swap :交换两个unique_ptr的内容std::unique_ptrOperate2 Operate2_1 std::make_uniqueOperate2(); Operate2_1-setValue(6);std::unique_ptrOperate2 Operate2_2 std::make_uniqueOperate2(); Operate2_2-setValue(9);std::cout Operate2_1: Operate2_1-getValue() Operate2_2: Operate2_1-getValue() std::endl;Operate2_1.swap(Operate2_2);std::cout Operate2_1: Operate2_1-getValue() Operate2_2: Operate2_1-getValue() std::endl;/*********************************************/// 函数结束,进入一次Operate2析构(ptr1)
}int main()
{// 基本操作2unique_operate2();/*输出为:call Operate2() 0000029218F50140print ptr1 ptr add:0000029218F50140print ptr2 - value is:10print ptr2 - value is:20tOperate2Ptr - value is:20call Operate2() 0000029218F501C0call ~Operate2() 0000029218F50140new print ptr2 - value is:10call ~Operate2() 0000029218F501C0call Operate2() 0000029218F50140call Operate2() 0000029218F501C0Operate2_1:6 Operate2_2:6Operate2_1:9 Operate2_2:9call ~Operate2() 0000029218F50140call ~Operate2() 0000029218F501C0*/return 0;
}基本操作3
#include iostreamclass TestClass
{
public:TestClass(){std::cout call TestClass() \t this std::endl;}TestClass(const TestClass ){std::cout call TestClass(const TestClass ) \t this std::endl;}~TestClass(){std::cout call ~TestClass() \t this std::endl;}TestClass* operator (int v){std::cout call TestClass \t this std::endl;TestClass *tmp new TestClass;tmp-value value v;return tmp;}// 设置value值void setValue(const int v){ value v; }// 获取value值int getValue()const { return value; }private:int value 100;
};std::unique_ptrTestClass changeValue_add10(std::unique_ptrTestClass tcPtr)
{tcPtr-setValue(tcPtr-getValue() 10);return tcPtr;
}void unique_operate3()
{std::unique_ptrTestClass tcPtr1 std::make_uniqueTestClass();if (tcPtr1) { std::cout 11111:\t ptr: tcPtr1 *ptr: tcPtr1-getValue() std::endl; }//changeValue_add10(stcPtr1); // 错误:由于unique_ptr不能拷贝,故不得作为形参进行拷贝给实参std::unique_ptrTestClass tcPtr2 changeValue_add10(std::move(tcPtr1));if (tcPtr2) { std::cout 22222:\t ptr: tcPtr2 *ptr: tcPtr2-getValue() std::endl; }
}int main()
{// 基本操作3unique_operate3();/*输出为:call TestClass() 000001F354580A6011111: ptr:000001F354580A60 *ptr:10022222: ptr:000001F354580A60 *ptr:110call ~TestClass() 000001F354580A60*/return 0;
}关注 笔者 - jxd
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/87767.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!