傻瓜式在线做网站,建筑网站模板,软件开发要多少钱,网站开发实践意义http://blog.csdn.net/Xiejingfa/article/details/50750037 原创作品#xff0c;转载请标明#xff1a;http://blog.csdn.net/Xiejingfa/article/details/50750037 C中的智能指针首先出现在“准”标准库boost中。随着使用的人越来越多#xff0c;为了让开发人员更方便、更安…http://blog.csdn.net/Xiejingfa/article/details/50750037 原创作品转载请标明http://blog.csdn.net/Xiejingfa/article/details/50750037 C中的智能指针首先出现在“准”标准库boost中。随着使用的人越来越多为了让开发人员更方便、更安全的使用动态内存C11也引入了智能指针来管理动态对象。在新标准中主要提供了shared_ptr、unique_ptr、weak_ptr三种不同类型的智能指针。接下来的几篇文章我们就来总结一下这些智能指针的使用。 今天我们先来看看shared_ptr智能指针。 shared_ptr shared_ptr是一个引用计数智能指针用于共享对象的所有权也就是说它允许多个指针指向同一个对象。这一点与原始指针一致。 先来一段简单的代码看看shared_ptr的简单使用
#include iostream
#include memory
using namespace std;class Example
{
public:Example() : e(1) { cout Example Constructor... endl; }~Example() { cout Example Destructor... endl; }int e;
};int main() {shared_ptrExample pInt(new Example());cout (*pInt).e endl;cout pInt引用计数: pInt.use_count() endl;shared_ptrExample pInt2 pInt;cout pInt引用计数: pInt.use_count() endl;cout pInt2引用计数: pInt2.use_count() endl;
}1234567891011121314151617181920212223 程序输出如下
Example Constructor...
pInt: 1
pInt引用计数: 1
pInt引用计数: 2
pInt2引用计数: 2
Example Destructor...123456 从上面这段代码中我们对shared_ptr指针有了一些直观的了解。一方面跟STL中大多数容器类型一样shared_ptr也是模板类因此在创建shared_ptr时需要指定其指向的类型。另一方面正如其名一样shared_ptr指针允许让多个该类型的指针共享同一堆分配对象。同时shared_ptr使用经典的“引用计数”方法来管理对象资源每个shared_ptr对象关联一个共享的引用计数。对于“引用计数”的问题这里就不展开介绍。有兴趣的同学可以上网查找资料或者看看我的另一篇文章 【Cocos2d-x源码分析】 Cocos2d-x内存管理解析Cocos2d-x也使用了“引用计数”方法来实现内存管理。 对于shared_ptr在拷贝和赋值时的行为《CPrimer第五版》中有详细的描述
每个shared_ptr都有一个关联的计数值通常称为引用计数。无论何时我们拷贝一个shared_ptr计数器都会递增。
例如当用一个shared_ptr初始化另一个shred_ptr或将它当做参数传递给一个函数以及作为函数的返回值时它
所关联的计数器就会递增。当我们给shared_ptr赋予一个新值或是shared_ptr被销毁例如一个局部的
shared_ptr离开其作用域时计数器就会递减。一旦一个shared_ptr的计数器变为0它就会自动释放自己所管理
的对象。12345 对比我们上面的代码可以看到当我们将一个指向Example对象的指针交给pInt管理后其关联的引用计数为1。接下来我们用pInt初始化pInt2两者关联的引用计数值增加为2。随后函数结束pInt和PInt2相继离开函数作用于相应的引用计数值分别自减1最后变为0于是Example对象被自动释放调用其析构函数。 接下来我们完整地介绍一下shared_ptr的常见用法 1、创建shared_ptr实例 最安全和高效的方法是调用make_shared库函数该函数会在堆中分配一个对象并初始化最后返回指向此对象的share_ptr实例。如果你不想使用make_ptr也可以先明确new出一个对象然后把其原始指针传递给share_ptr的构造函数。 示例如下
int main() {// 传递给make_shared函数的参数必须和shared_ptr所指向类型的某个构造函数相匹配shared_ptrstring pStr make_sharedstring(10, a);cout *pStr endl; // aaaaaaaaaaint *p new int(5);shared_ptrint pInt(p);cout *pInt endl; // 5
}12345678910 2、访问所指对象 shared_ptr的使用方式与普通指针的使用方式类似既可以使用解引用操作符*获得原始对象进而访问其各个成员也可以使用指针访问符-来访问原始对象的各个成员。 3、拷贝和赋值操作 我们可以用一个shared_ptr对象来初始化另一个share_ptr实例该操作会增加其引用计数值。 例如
int main() {shared_ptrstring pStr make_sharedstring(10, a);cout pStr.use_count() endl; // 1shared_ptrstring pStr2(pStr);cout pStr.use_count() endl; // 2cout pStr2.use_count() endl; // 2
}12345678 如果shared_ptr实例p和另一个shared_ptr实例q所指向的类型相同或者可以相互转换我们还可以进行诸如p q这样赋值操作。该操作会递减p的引用计数值递增q的引用计数值。 例如
class Example
{
public:Example(string n) : name(n) { cout n constructor... endl; }~Example() { cout name destructor... endl; }string name;
};int main() {shared_ptrExample pStr make_sharedExample(a object);shared_ptrExample pStr2 make_sharedExample(b object);cout pStr.use_count() endl;cout pStr2.use_count() endl;pStr pStr2; // 此后pStr和pStr指向相同对象cout pStr-name endl;cout pStr2-name endl;
}1234567891011121314151617181920 输出如下
a object constructor...
b object constructor...
1
1
a object destructor...
b object
b object
b object destructor...12345678 4、检查引用计数 shared_ptr提供了两个函数来检查其共享的引用计数值分别是unique()和use_count()。 在前面我们已经多次使用过use_count()函数该函数返回当前指针的引用计数值。值得注意的是use_count()函数可能效率很低应该只把它用于测试或调试。 unique()函数用来测试该shared_ptr是否是原始指针唯一拥有者也就是use_count()的返回值为1时返回true否则返回false。 示例
int main() {shared_ptrstring pStr make_sharedstring(10, a);cout pStr.unique() endl; // trueshared_ptrstring pStr2(pStr);cout pStr2.unique() endl; // false;
}