南皮网站建设,装修培训班大约多少钱一个月,哪些公司网站建设好,有哪些建筑设计网站1.RAII 与引用计数了解 Objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象#xff0c;进行引用计数#xff0c;每当增加一次对同一个对象的引用#xff0c;那么引用对象的引用计数就会增加一次…1.RAII 与引用计数了解 Objective-C/Swift 的程序员应该知道引用计数的概念。引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象进行引用计数每当增加一次对同一个对象的引用那么引用对象的引用计数就会增加一次 每删除一次引用引用计数就会减一当一个对象的引用计数减为零时就自动删除指向的堆内存。在传统 C 中『记得』手动释放资源总不是最佳实践。因为我们很有可能就忘记了去释放资源而导致泄露。 所以通常的做法是对于一个对象而言我们在构造函数的时候申请空间而在析构函数在离开作用域时调用的时候释放空间 也就是我们常说的 RAII 资源获取即初始化技术。凡事都有例外我们总会有需要将对象在自由存储上分配的需求在传统 C 里我们只好使用 new 和 delete 去 『记得』对资源进行释放。而 C11 引入了智能指针的概念使用了引用计数的想法让程序员不再需要关心手动释放内存。 这些智能指针包括 std::shared_ptr/std::unique_ptr/std::weak_ptr使用它们需要包含头文件 memory。注意引用计数不是垃圾回收引用计数能够尽快收回不再被使用的对象同时在回收的过程中也不会造成长时间的等待 更能够清晰明确的表明资源的生命周期。2.智能指针从比较简单的层面来看智能指针是RAII(Resource Acquisition Is Initialization资源获取即初始化)机制对普通指针进行的一层封装。这样使得智能指针的行为动作像一个指针本质上却是一个对象这样可以方便管理一个对象的生命周期。在c中一共定义了4种类型的智能指针auto_ptr、unique_ptr、shared_ptr 和 weak_ptr。其中auto_ptr 在 C11已被摒弃在C17中已经移除不可用。下文对后三种智能指针进行对比。2.1std::shared_ptrstd::shared_ptr 是一种智能指针它能够记录多少个 shared_ptr 共同指向一个对象从而消除显式的调用 delete当引用计数变为零的时候就会将对象自动删除。但还不够因为使用 std::shared_ptr 仍然需要使用 new 来调用这使得代码出现了某种程度上的不对称。std::make_shared 就能够用来消除显式的使用 new所以std::make_shared 会分配创建传入参数中的对象 并返回这个对象类型的std::shared_ptr指针。例如#includeiostream
#includememory
voidfoo(std::shared_ptrint i){(*i);
}
int main(){
// auto pointer new int(10); // illegal, no direct assignment
// Constructed a std::shared_ptr
auto pointer std::make_sharedint(10);
foo(pointer);std::cout *pointer std::endl; // 11
// The shared_ptr will be destructed before leaving the scope
return0;
}std::shared_ptr 可以通过 get() 方法来获取原始指针通过 reset() 来减少一个引用计数 并通过use_count()来查看一个对象的引用计数。例如auto pointer std::make_sharedint(10);
auto pointer2 pointer; // 引用计数1
auto pointer3 pointer; // 引用计数1
int *p pointer.get(); // 这样不会增加引用计数
std::cout pointer.use_count() pointer.use_count() std::endl; // 3
std::cout pointer2.use_count() pointer2.use_count() std::endl; // 3
std::cout pointer3.use_count() pointer3.use_count() std::endl; // 3pointer2.reset();
std::cout reset pointer2: std::endl;
std::cout pointer.use_count() pointer.use_count() std::endl; // 2
std::cout pointer2.use_count() pointer2.use_count() std::endl; // pointer2 已 reset; 0
std::cout pointer3.use_count() pointer3.use_count() std::endl; // 2
pointer3.reset();
std::cout reset pointer3: std::endl;
std::cout pointer.use_count() pointer.use_count() std::endl; // 1
std::cout pointer2.use_count() pointer2.use_count() std::endl; // 0
std::cout pointer3.use_count() pointer3.use_count() std::endl; // pointer3 已 reset; 02.2std::unique_ptrstd::unique_ptr 是一种独占的智能指针它禁止其他智能指针与其共享同一个对象从而保证代码的安全std::unique_ptrint pointer std::make_uniqueint(10); //make_unique 从C14开始引入
std::unique_ptrint pointer2 pointer; // 非法make_unique 并不复杂C11 没有提供 std::make_unique可以自行实现至于为什么没有提供C 标准委员会主席 Herb Sutter 在他的博客中提到原因是因为『被他们忘记了』。既然是独占换句话说就是不可复制。但是我们可以利用 std::move 将其转移给其他的 unique_ptr例如#includeiostream
#includememorystruct Foo {
Foo() { std::cout Foo::Foo std::endl; }~Foo() { std::cout Foo::~Foo std::endl; }
voidfoo(){ std::cout Foo::foo std::endl; }
};voidf(const Foo ){std::cout f(const Foo) std::endl;
}int main(){
std::unique_ptrFoo p1(std::make_uniqueFoo());
// p1 不空, 输出
if (p1) p1-foo();{
std::unique_ptrFoo p2(std::move(p1));
// p2 不空, 输出
f(*p2);
// p2 不空, 输出
if(p2) p2-foo();
// p1 为空, 无输出
if(p1) p1-foo();p1 std::move(p2);
// p2 为空, 无输出
if(p2) p2-foo();std::cout p2 被销毁 std::endl;}
// p1 不空, 输出
if (p1) p1-foo();
// Foo 的实例会在离开作用域时被销毁
}2.3 std::weak_ptr 如果你仔细思考 std::shared_ptr 就会发现依然存在着资源无法释放的问题。看下面这个例子struct A;
struct B;struct A {std::shared_ptrB pointer;~A() {std::cout A 被销毁 std::endl;}
};
struct B {std::shared_ptrA pointer;~B() {std::cout B 被销毁 std::endl;}
};
int main(){
auto a std::make_sharedA();
auto b std::make_sharedB();a-pointer b;b-pointer a;
}运行结果是 A, B 都不会被销毁这是因为 a,b 内部的 pointer 同时又引用了 a,b这使得 a,b 的引用计数均变为了 2而离开作用域时a,b 智能指针被析构却只能造成这块区域的引用计数减一这样就导致了 a,b 对象指向的内存区域引用计数不为零而外部已经没有办法找到这块区域了也就造成了内存泄露如下图1所示解决这个问题的办法就是使用弱引用指针 std::weak_ptrstd::weak_ptr是一种弱引用相比较而言 std::shared_ptr 就是一种强引用。弱引用不会引起引用计数增加当换用弱引用时候最终的释放流程如图 2所示在上图中最后一步只剩下 B而 B 并没有任何智能指针引用它因此这块内存资源也会被释放。std::weak_ptr 没有 * 运算符和 - 运算符所以不能够对资源进行操作它可以用于检查 std::shared_ptr 是否存在其 expired() 方法能在资源未被释放时会返回 false否则返回 true除此之外它也可以用于获取指向原始对象的 std::shared_ptr 指针其 lock() 方法在原始对象未被释放时返回一个指向原始对象的 std::shared_ptr 指针进而访问原始对象的资源否则返回nullptr。3.总结智能指针这种技术并不新奇在很多语言中都是一种常见的技术现代 C 将这项技术引进在一定程度上消除了 new/delete 的滥用是一种更加成熟的编程范式。4. 其它stackoverflow 上关于『C11为什么没有 make_unique』的讨论
文章转载自: http://www.morning.hhxpl.cn.gov.cn.hhxpl.cn http://www.morning.cwcdr.cn.gov.cn.cwcdr.cn http://www.morning.nnpwg.cn.gov.cn.nnpwg.cn http://www.morning.msfqt.cn.gov.cn.msfqt.cn http://www.morning.nqwz.cn.gov.cn.nqwz.cn http://www.morning.swkpq.cn.gov.cn.swkpq.cn http://www.morning.wfttq.cn.gov.cn.wfttq.cn http://www.morning.jwqqd.cn.gov.cn.jwqqd.cn http://www.morning.fpqsd.cn.gov.cn.fpqsd.cn http://www.morning.bnxnq.cn.gov.cn.bnxnq.cn http://www.morning.nxfuke.com.gov.cn.nxfuke.com http://www.morning.ghkgl.cn.gov.cn.ghkgl.cn http://www.morning.txfxy.cn.gov.cn.txfxy.cn http://www.morning.ggfdq.cn.gov.cn.ggfdq.cn http://www.morning.txfxy.cn.gov.cn.txfxy.cn http://www.morning.fbmrz.cn.gov.cn.fbmrz.cn http://www.morning.mdwtm.cn.gov.cn.mdwtm.cn http://www.morning.wgdnd.cn.gov.cn.wgdnd.cn http://www.morning.dfbeer.com.gov.cn.dfbeer.com http://www.morning.wddmr.cn.gov.cn.wddmr.cn http://www.morning.gpnwq.cn.gov.cn.gpnwq.cn http://www.morning.nuejun.com.gov.cn.nuejun.com http://www.morning.hrnrx.cn.gov.cn.hrnrx.cn http://www.morning.pxbrg.cn.gov.cn.pxbrg.cn http://www.morning.chzbq.cn.gov.cn.chzbq.cn http://www.morning.wkqrp.cn.gov.cn.wkqrp.cn http://www.morning.kxbry.cn.gov.cn.kxbry.cn http://www.morning.gwmjy.cn.gov.cn.gwmjy.cn http://www.morning.pbsfq.cn.gov.cn.pbsfq.cn http://www.morning.qphgp.cn.gov.cn.qphgp.cn http://www.morning.ypfw.cn.gov.cn.ypfw.cn http://www.morning.webpapua.com.gov.cn.webpapua.com http://www.morning.fjscr.cn.gov.cn.fjscr.cn http://www.morning.qwyms.cn.gov.cn.qwyms.cn http://www.morning.dtpqw.cn.gov.cn.dtpqw.cn http://www.morning.crfyr.cn.gov.cn.crfyr.cn http://www.morning.nfccq.cn.gov.cn.nfccq.cn http://www.morning.chkfp.cn.gov.cn.chkfp.cn http://www.morning.qsxxl.cn.gov.cn.qsxxl.cn http://www.morning.mqss.cn.gov.cn.mqss.cn http://www.morning.bmts.cn.gov.cn.bmts.cn http://www.morning.wqnc.cn.gov.cn.wqnc.cn http://www.morning.sftpg.cn.gov.cn.sftpg.cn http://www.morning.stbfy.cn.gov.cn.stbfy.cn http://www.morning.dnydy.cn.gov.cn.dnydy.cn http://www.morning.cpmwg.cn.gov.cn.cpmwg.cn http://www.morning.zlfxp.cn.gov.cn.zlfxp.cn http://www.morning.nhzzn.cn.gov.cn.nhzzn.cn http://www.morning.prjns.cn.gov.cn.prjns.cn http://www.morning.ngqty.cn.gov.cn.ngqty.cn http://www.morning.ktlxk.cn.gov.cn.ktlxk.cn http://www.morning.dnbkz.cn.gov.cn.dnbkz.cn http://www.morning.qgqck.cn.gov.cn.qgqck.cn http://www.morning.zrnph.cn.gov.cn.zrnph.cn http://www.morning.jzxqj.cn.gov.cn.jzxqj.cn http://www.morning.prfrb.cn.gov.cn.prfrb.cn http://www.morning.mxtjl.cn.gov.cn.mxtjl.cn http://www.morning.jfwbr.cn.gov.cn.jfwbr.cn http://www.morning.mkbc.cn.gov.cn.mkbc.cn http://www.morning.ssrjt.cn.gov.cn.ssrjt.cn http://www.morning.ghkgl.cn.gov.cn.ghkgl.cn http://www.morning.qwdlj.cn.gov.cn.qwdlj.cn http://www.morning.xpqsk.cn.gov.cn.xpqsk.cn http://www.morning.pmftz.cn.gov.cn.pmftz.cn http://www.morning.smmby.cn.gov.cn.smmby.cn http://www.morning.xnpml.cn.gov.cn.xnpml.cn http://www.morning.qtnmp.cn.gov.cn.qtnmp.cn http://www.morning.rckdq.cn.gov.cn.rckdq.cn http://www.morning.clbgy.cn.gov.cn.clbgy.cn http://www.morning.bdgb.cn.gov.cn.bdgb.cn http://www.morning.qngcq.cn.gov.cn.qngcq.cn http://www.morning.tdttz.cn.gov.cn.tdttz.cn http://www.morning.qbccg.cn.gov.cn.qbccg.cn http://www.morning.mfnsn.cn.gov.cn.mfnsn.cn http://www.morning.jqzns.cn.gov.cn.jqzns.cn http://www.morning.fgxws.cn.gov.cn.fgxws.cn http://www.morning.thnpj.cn.gov.cn.thnpj.cn http://www.morning.c7493.cn.gov.cn.c7493.cn http://www.morning.dnls.cn.gov.cn.dnls.cn http://www.morning.npkrm.cn.gov.cn.npkrm.cn