📄 autoptr.html
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="css/stdlayout.css" type="text/css">
<link rel="stylesheet" href="css/print.css" type="text/css">
<meta content="text/html; charset=gb2312" http-equiv="content-type">
<title>auto_ptr 自动管理配置资源</title>
</head>
<body>
<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>
<h1><a href="CppGossip.html">C++
Gossip: auto_ptr 自动管理配置资源</a></h1>
对于使用new动态配置的资源,在不使用时必须记得delete,以释放记忆体空间,然而动态记忆体配置很容易发生忘了delete,或是对同一个记忆体
位址delete两次(例如一个物件被指定给两个指标),或是对一个已经被delete的位址再作读写动作。<br>
<br>
C++标准函式库中提供auto_prt,可以协助您动态管理new而建立的物件,要使用auto_prt,您要含入memory表头档,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">#include <memory></span><br>
</div>
<br>
auto_ptr可以指向一个以new建立的物件,当auto_ptr的生命周期结束后,所指向的物件之资源也会被释放,在建立auto_ptr时必须指
定目标物件之型态,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">auto_ptr<int>
iPtr (new int(100));</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">auto_ptr<string>
sPtr (new string("caterpillar"));</span><br>
</div>
<br>
操作auto_ptr就像操作没有使用auto_ptr的指标一样,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">cout << *iPtr
<< endl; // 显示100<br>
if(sPtr->empty())<br>
cout << "字串为空" << endl;</span><span style="font-weight: bold; font-style: italic;"><br>
</span></div>
<br>
您也可以建立一个未指向任何物件的auto_prt,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">auto_ptr<int>
iPtr;</span><br>
</div>
<br>
未指向任何物件的auto_ptr不可以取值,否则会发生不可预期之结果,即然不可取值,如何判断它是否有指向物件呢?您可以使用get()函式,它会传
回所指向物件的位址,如果传回0,表示不指向任何物件,如果不指向任何物件,您可以使用reset()来让它指向一个物件,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">if(iPtr.get() == 0) {</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">
iPtr.reset(new int(100));</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">}</span><br>
</div>
<br>
reset()可以接受一个指标或是0表示不指向任何物件,reset()会先delete目前指向的物件,然后重新指向新的物件,您也可以使用
release()释放auto_ptr管理所指向物件的职责。<br>
<br>
auto_ptr可以使用另一个auto_ptr来建立,这会造成所有权的转移,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">auto_ptr<SafeArray>
ptr1(new SafeArray(19));</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">auto_ptr<SafeArray>
ptr2(ptr1);</span><br>
</div>
<br>
当使用ptr1来建立ptr2时,ptr1不再对所指向物件的资源释放负责,职责交给了ptr2,在使用指定运算时,也有类似的行为,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">auto_ptr<SafeArray>
ptr1(new SafeArray(19));</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">auto_ptr<SafeArray>
ptr2(new SafeArray(20));</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">ptr2 = ptr1;</span><br>
</div>
<br>
ptr2所指向的物件会先被delete,然后ptr1的属性会复制至ptr2,也就是ptr1所指向的物件,现在由ptr2指向它了,ptr1不再负责
所指向物件的资源释放。<br>
<br>
auto_ptr的资源维护动作是以inline的方式来完成,也就是在编译时会被扩展开来,所以使用auto_ptr并不会牺牲效率。<br>
<br>
最后要注意的是,auto_ptr不能用来管理动态配置而来的阵列,如果用它来管理动态配置而来的阵列,结果是不可预期的。<br>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -