#
.net開源項(xiàng)目
http://www.cnblogs.com/apollo086574/archive/2007/10/06/915298.html
列數(shù).NET開源項(xiàng)目 paint
http://www.getpaint.net/index.htmlAbout Apache log4net
log4net is a tool to help the programmer output log statements to a variety of output targets. log4net is a port of the excellent log4j framework to the .NET runtime. We have kept the framework similar in spirit to the original log4j while taking advantage of new features in the .NET runtime. For more information on log4net see the features document.
log4net is part of the Apache Logging Services project. The Logging Services project is intended to provide cross-language logging services for purposes of application debugging and auditing.
http://logging.apache.org/log4net/download.htmlNunit
對(duì)應(yīng)Java中的Junit,非常著名的單元測(cè)試工具。
鏈接:http://www.nunit.org/Nlog
一個(gè)日志管理庫,類似于Log4Net。
鏈接:http://www.nlog-project.org/
class test
{
public:
void (test::*p)();
void Print(){cout<<"Test"<<endl;}
test(){p = &test::Print;}
};
void (test::*q)();
標(biāo)準(zhǔn)C++編程:虛函數(shù)與內(nèi)聯(lián)
Josée Lajoie and Stanley Lippman
------------------------------------------------------------------------------
----
[This is the last installment of a column that was being published in C++ Repo
rt magazine. Since the magazine ceased publication before this installment cou
ld be published, Josée Lajoie and Stan Lippman were gracious enough to let us
publish it on the CUJ website. — mb]
曾經(jīng),我們常常在談及C++時(shí)聽到一個(gè)問題:“虛函數(shù)真的應(yīng)該被申明為內(nèi)聯(lián)嗎?”現(xiàn)在,
我們很少再聽到這個(gè)問題了。反過來,我們現(xiàn)在聽到的是“你不應(yīng)該將print()函數(shù)內(nèi)聯(lián)。
將虛函數(shù)申明為內(nèi)聯(lián)是錯(cuò)誤的。”
這么說有兩個(gè)主要理由:(1)虛函數(shù)是在運(yùn)行期判決的,而內(nèi)聯(lián)是編譯期行為,所以不能從
這個(gè)(內(nèi)聯(lián))申明上得到任何好處;(2)將虛函數(shù)申明為內(nèi)聯(lián)將造成此函數(shù)在可執(zhí)行文件中
有多份拷貝,因此我們?yōu)橐粋€(gè)無論如何都不能內(nèi)聯(lián)的函數(shù)付出了在空間上的處罰(WQ注,
所謂的內(nèi)聯(lián)函數(shù)非內(nèi)聯(lián)問題)。顯然沒腦子。
只是它并不真的正確。反思一下理由(1):在很多情況下,虛函數(shù)是靜態(tài)判決的--尤其是
派生類的虛函數(shù)調(diào)用它的基類版本時(shí)。為什么會(huì)那么做?封裝。一個(gè)很好的例子是析構(gòu)函
數(shù)的靜態(tài)調(diào)用鏈:基類的析構(gòu)函數(shù)被派生類的析構(gòu)函數(shù)觸發(fā)。除了最初的一個(gè)外,所有的
析構(gòu)函數(shù)的調(diào)用都是被靜態(tài)判決的。不讓基類的虛析構(gòu)函數(shù)內(nèi)聯(lián),就不能從中獲益。這會(huì)
造成很大的差別嗎?如果繼承層次很深,而又有大量的對(duì)象需要析構(gòu),(答案是)“是的
”。
另外一個(gè)例子不涉及析構(gòu)函數(shù)。想像我們正在設(shè)計(jì)一個(gè)圖書館出借管理程序。我們已經(jīng)將
“位置”放入抽象類LibraryMaterial。當(dāng)申明print()函數(shù)為純虛函數(shù)時(shí),我們也提供其
定義:打印出對(duì)象的位置。
class LibraryMaterial {
private:
MaterialLocation _loc; // shared data
// ...
public:
// declares pure virtual function
inline virtual void print( ostream& = cout ) = 0;
};
// we actually want to encapsulate the handling of the
// location of the material within a base class
// LibraryMaterial print() method - we just don’t want it
// invoked through the virtual interface. That is, it is
// only to be invoked within a derived class print() method
inline void
LibraryMaterial::
print( ostream &os ) { os << _loc; }
接著引入Book類;它的print()函數(shù)會(huì)輸出書名、作者等等。在此之前,它先調(diào)用基類的L
ibraryMaterial::print()函數(shù)以顯示位置信息。例如:
inline void
Book::
print( ostream &os )
{
// ok, this is resolved statically,
// and therefore is inline expanded ...
LibraryMaterial::print();
os << "title:" << _title
<< "author" << _author << endl;
}
AudioBook類從Book派生,引入了一個(gè)二選一的借出策略,并且加入了一些附加信息,比如
講解員、格式等等。這些都將在它的print()函數(shù)中顯示出來。在顯示這些以前,它先調(diào)用
Book::print():
inline void
AudioBook::
print( ostream &os )
{
// ok, this is resolved statically,
// and therefore is inline expanded ...
Book::print();
os << "narrator:" << _narrator << endl;
}
在這個(gè)例子和析構(gòu)函數(shù)的例子中,派生類的虛方法遞增式地?cái)U(kuò)展其基類版本的功能,并以
調(diào)用鏈的方式被調(diào)用,只有最初一次調(diào)用是由虛體系決定的。這個(gè)沒有被命名的繼承樹設(shè)
計(jì)模式,如果從不將虛函數(shù)申明為內(nèi)聯(lián)的話,顯然會(huì)有些低效。
關(guān)于理由(2)的代碼膨脹問題怎么說?好吧,思考一下。如果寫出,
LibraryMaterial *p =
new AudioBook( "Mason & Dixon",
"Thomas Pynchon", "Johnny Depp" );
// ...
p->print();
此處的print()會(huì)內(nèi)聯(lián)嗎?不,當(dāng)然不會(huì)。這必須在運(yùn)行期經(jīng)過虛體系的判決。Okay。它會(huì)
導(dǎo)致此處的print()函數(shù)有它自己的定義體嗎?也不會(huì)。調(diào)用被編譯為類似于這種形式:
// Pseudo C++ Code
// Possible transformation of p->print()
( *p->_vptr[ 2 ] )( p );
那個(gè)2是print()函數(shù)在相應(yīng)的虛函數(shù)表中的位置。因?yàn)檫@個(gè)對(duì)print()的調(diào)用是通過函數(shù)指
針_vptr[2]進(jìn)行的,編譯器不能靜態(tài)決定被調(diào)用函數(shù)的位置,并且函數(shù)不能被內(nèi)聯(lián)。
當(dāng)然,內(nèi)聯(lián)的虛函數(shù)print()的定義必須出現(xiàn)在可執(zhí)行文件中的某處,代碼才能正確執(zhí)行。
也就是說,至少需要一個(gè)定義體,以便將它的地址放入虛函數(shù)表。編譯器如何決定何時(shí)產(chǎn)
生那一個(gè)定義體的呢?一個(gè)實(shí)現(xiàn)策略是在產(chǎn)生那類的虛函數(shù)表時(shí)同時(shí)產(chǎn)生那個(gè)定義體。這
意味著針對(duì)為一個(gè)類所生成的每個(gè)虛函數(shù)表實(shí)例,每個(gè)內(nèi)聯(lián)的虛函數(shù)的一個(gè)實(shí)例也被產(chǎn)生
。
在可執(zhí)行文件中,為一個(gè)類產(chǎn)生的虛函數(shù)表,實(shí)際上有多少個(gè)?啊,很好,問得好。C++標(biāo)
準(zhǔn)規(guī)定了虛函數(shù)在行為上的要求;但它沒有規(guī)定實(shí)現(xiàn)虛函數(shù)上的要求。既然虛函數(shù)表的存
在不是C++標(biāo)準(zhǔn)所要求的,明顯標(biāo)準(zhǔn)也沒有進(jìn)一步要求如何處理虛函數(shù)表以及生成多少次。
最佳的數(shù)目當(dāng)然是“一次”。例如,Stroustrup的原始cfront實(shí)現(xiàn)版本,在大部份情況下
聰明地達(dá)成了這一點(diǎn)。 (Stan和Andy Koenig描述了其算法,發(fā)表于1990年3月,C++ Repo
rt,“Optimizing Virtual Tables in C++ Release 2.0.”)
此外,C++標(biāo)準(zhǔn)現(xiàn)在要求內(nèi)聯(lián)函數(shù)的行為要滿足好象程序中只存在一個(gè)定義體,即使這個(gè)函
數(shù)可能被定義在不同的文件中。新的規(guī)則是說滿足規(guī)定的實(shí)現(xiàn)版本,行為上應(yīng)該好象只生
成了一個(gè)實(shí)例。一旦標(biāo)準(zhǔn)的這一點(diǎn)被廣泛采用,對(duì)內(nèi)聯(lián)函數(shù)潛在的代碼膨脹問題的關(guān)注應(yīng)
該消失了。
C++社群中存在著一個(gè)沖突:教學(xué)上需要規(guī)則表現(xiàn)為簡(jiǎn)單的檢查表vs實(shí)踐中需要明智地依據(jù)
環(huán)境而運(yùn)用規(guī)則。前者是對(duì)語言的復(fù)雜度的回應(yīng);后者,是對(duì)我們構(gòu)造的解決方案的復(fù)雜
度的回應(yīng)。何時(shí)將虛函數(shù)申明為內(nèi)聯(lián)的問題,是這種沖突的一個(gè)很好的例證。
About the Authors
Stanley Lippman was the software Technical Director for the Firebird segment o
f Disney's Fantasia 2000. He was recently technical lead on the ToonShooter im
age capture and playback system under Linux for DreamWorks Feature Animation a
nd consulted with the Jet Propulsion Laboratory. He is currently IT Training P
rogram Chair for You-niversity.com, an e-learning training company. He can be
reached at stanleyl@you-niversity, www.you-niversity.com, and www.objectwrite.
com.
Josée Lajoie is currently doing her Master's degree in Computer Graphics at t
he University Waterloo. Previously, she was a member of the C/C++ compiler dev
elopment team at the IBM Canada Laboratory and was the chair of the core langu
age working group for the ANSI/ISO C++ Standard Committee. She can be reached
at jlajoie@cgl.uwaterloo.ca.
類的成員函數(shù)分為兩種,一種是靜態(tài)函數(shù),另外一種是非靜態(tài)函數(shù)。例如:
class X
{
public:
static void display();
bool getValue();
}
display()為靜態(tài)函數(shù),getValue即為非靜態(tài)函數(shù)。兩種函數(shù)在使用的時(shí)候是不一樣的。靜態(tài)函數(shù)
可以直接由類名來調(diào)用,而非靜態(tài)函數(shù)則必須通過某一個(gè)對(duì)象來調(diào)用,例如:
X::display();
X x;
x.getValue();
為什么會(huì)出現(xiàn)這樣的情況了?這是由于編譯器在處理這兩種函數(shù)的方式不同造成的。靜態(tài)函數(shù)在
運(yùn)行期只有一份拷貝,所有該類生成的對(duì)象共享該函數(shù)以及該函數(shù)的內(nèi)部變量。而對(duì)于非靜態(tài)函數(shù),
不同的對(duì)象擁有自己的內(nèi)部變量。
靜態(tài)成員函數(shù)與普通成員函數(shù)的差別就在于缺少this指針,沒有這個(gè)this指針自然也就無從知道name是哪一個(gè)對(duì)象的成員了。
根據(jù)類靜態(tài)成員的特性我們可以簡(jiǎn)單歸納出幾點(diǎn),靜態(tài)成員的使用范圍:
1.用來保存對(duì)象的個(gè)數(shù)。
2.作為一個(gè)標(biāo)記,標(biāo)記一些動(dòng)作是否發(fā)生,比如:文件的打開狀態(tài),打印機(jī)的使用狀態(tài),等等。
3.存儲(chǔ)鏈表的第一個(gè)或者最后一個(gè)成員的內(nèi)存地址。
為了做一些必要的練習(xí),深入的掌握靜態(tài)對(duì)象的存在的意義,我們以前面的結(jié)構(gòu)體的教程為基礎(chǔ),用類的方式描述一個(gè)線性鏈表,用于存儲(chǔ)若干學(xué)生的姓名,代碼如下:
對(duì)于靜態(tài)成員函數(shù)的一些限制
1.靜態(tài)成員函數(shù)只能引用這個(gè)類的其他靜態(tài)成員(當(dāng)然也可以訪問全局函數(shù)和數(shù)據(jù))。
2.靜態(tài)成員函數(shù)沒有this指針。
3.同一個(gè)函數(shù)不能有靜態(tài)和非靜態(tài)兩種版本,靜態(tài)成員函數(shù)不可以是虛函數(shù)。
4.它們不能被聲明為const或volatile。
靜態(tài)成員函數(shù)也屬于整個(gè)類,所以可以通過使用類名和作用域分辨符被其本身調(diào)用(獨(dú)立于對(duì)象),也可以和對(duì)象聯(lián)系起來調(diào)用。
實(shí)際上,靜態(tài)成員函數(shù)的應(yīng)用是有限的,使用它的好處是在實(shí)際創(chuàng)建任何對(duì)象之前可以“預(yù)初始化”私有的靜態(tài)數(shù)據(jù)。
在函數(shù)調(diào)用過程中,會(huì)使用堆棧,這三個(gè)表示不同的堆棧調(diào)用方式和釋放方式。
比如說__cdecl,它是標(biāo)準(zhǔn)的c方法的堆棧調(diào)用方式,就是在函數(shù)調(diào)用時(shí)的參數(shù)壓入堆棧是與函數(shù)的聲明順序相反的,其它兩個(gè)可以看MSDN,不過這個(gè)對(duì)我們編程沒有太大的作用
調(diào)用約定
調(diào)用約定(Calling convention)決定以下內(nèi)容:函數(shù)參數(shù)的壓棧順序,由調(diào)用者還是被調(diào)用者把參數(shù)彈出棧,以及產(chǎn)生函數(shù)修飾名的方法。MFC支持以下調(diào)用約定:
_cdecl
按從右至左的順序壓參數(shù)入棧,由調(diào)用者把參數(shù)彈出棧。對(duì)于"C"函數(shù)或者變量,修飾名是在函數(shù)名前加下劃線。對(duì)于"C++"函數(shù),有所不同。
如函數(shù)void test(void)的修飾名是_test;對(duì)于不屬于一個(gè)類的"C++"全局函數(shù),修飾名是?test@@ZAXXZ。
這是MFC缺省調(diào)用約定。由于是調(diào)用者負(fù)責(zé)把參數(shù)彈出棧,所以可以給函數(shù)定義個(gè)數(shù)不定的參數(shù),如printf函數(shù)。
_stdcall
按從右至左的順序壓參數(shù)入棧,由被調(diào)用者把參數(shù)彈出棧。對(duì)于"C"函數(shù)或者變量,修飾名以下劃線為前綴,然后是函數(shù)名,然后是符號(hào)"@"及參數(shù)的字節(jié)數(shù),如函數(shù)int func(int a, double b)的修飾名是_func@12。對(duì)于"C++"函數(shù),則有所不同。
所有的Win32 API函數(shù)都遵循該約定。
_fastcall
頭兩個(gè)DWORD類型或者占更少字節(jié)的參數(shù)被放入ECX和EDX寄存器,其他剩下的參數(shù)按從右到左的順序壓入棧。由被調(diào)用者把參數(shù)彈出棧,對(duì)于"C"函數(shù)或者變量,修飾名以"@"為前綴,然后是函數(shù)名,接著是符號(hào)"@"及參數(shù)的字節(jié)數(shù),如函數(shù)int func(int a, double b)的修飾名是@func@12。對(duì)于"C++"函數(shù),有所不同。
未來的編譯器可能使用不同的寄存器來存放參數(shù)。
關(guān)鍵字 調(diào)用規(guī)則 參數(shù)傳遞方向 返回 參數(shù)寄存器 堆棧的清除
__cdecl C調(diào)用規(guī)則 從右向左 EAX 無 調(diào)用者
__fastcall 寄存器 從左向右 EAX EAX、EBX、ECX 被調(diào)用者
__stdcall Win32標(biāo)準(zhǔn) 從右向左 EAX 無 被調(diào)用者
__pascal Pascal 從左向右 EAX 無 被調(diào)用者
__msfastcall Ms寄存器 從右向左 EAX/EDX ECX、EDX 被調(diào)用者
C++ Builder中幾種調(diào)用規(guī)則的比較
1. 名字分解:
沒有名字分解的函數(shù)
TestFunction1 // __cdecl calling convention
@TestFunction2 // __fastcall calling convention
TESTFUNCTION3 // __pascal calling convention
TestFunction4 // __stdcall calling convention
有名字分解的函數(shù)
@TestFunction1$QV // __cdecl calling convention
@TestFunction2$qv // __fastcall calling convention
TESTFUNCTION3$qqrv // __apscal calling convention
@TestFunction4$qqrv // __stdcall calling convention
使用 extern "C" 不會(huì)分解函數(shù)名
使用 Impdef MyLib.def MyLib.dll 生成 def 文件查看是否使用了名字分解
2. 調(diào)用約定:
__cdecl 缺省
是 Borland C++ 的缺省的 C 格式命名約定,它在標(biāo)識(shí)符前加一下劃線,以保留
它原來所有的全程標(biāo)識(shí)符。參數(shù)按最右邊參數(shù)優(yōu)先的原則傳遞給棧,然后清棧。
extaern "C" bool __cdecl TestFunction();
在 def 文件中顯示為
TestFunction @1
注釋: @1 表示函數(shù)的順序數(shù),將在“使用別名”時(shí)使用。
__pascal Pascal格式
這時(shí)函數(shù)名全部變成大寫,第一個(gè)參數(shù)先壓棧,然后清棧。
TESTFUNCTION @1 //def file
__stdcall 標(biāo)準(zhǔn)調(diào)用
最后一個(gè)參數(shù)先壓棧,然后清棧。
TestFunction @1 //def file
__fastcall 把參數(shù)傳遞給寄存器
第一個(gè)參數(shù)先壓棧,然后清棧。
@TestFunction @1 //def file
3. 解決調(diào)用約定:
Microsoft 與 Borland 的 __stdcall 之間的區(qū)別是命名方式。 Borland 采用
__stdcall 的方式去掉了名字起前的下劃線。 Microsoft 則是在前加上下劃線,在
后加上 @ ,再后跟為棧保留的字節(jié)數(shù)。字節(jié)數(shù)取決于參數(shù)在棧所占的空間。每一個(gè)
參數(shù)都舍入為 4 的倍數(shù)加起來。這種 Miocrosoft 的 Dll 與系統(tǒng)的 Dll 不一樣。
4. 使用別名:
使用別名的目的是使調(diào)用文件 .OBJ 與 DLL 的 .DEF 文件相匹配。如果還沒有
.DEF 文件,就應(yīng)該先建一個(gè)。然后把 DEF 文件加入 Project。使用別名應(yīng)不斷
修改外部錯(cuò)誤,如果沒有,還需要將 IMPORTS 部分加入 DEF 文件。
IMPORTS
TESTFUNCTIOM4 = dllprj.TestFunction4
TESTFUNCTIOM5 = dllprj.WEP @500
TESTFUNCTIOM6 = dllprj.GETHOSTBYADDR @51
這里需要說明的是,調(diào)用應(yīng)用程序的 .OBJ 名與 DLL 的 .DEF 文件名是等價(jià)的,
而且總是這樣。甚至不用考慮調(diào)用約定,它會(huì)自動(dòng)匹配。在前面的例子中,函數(shù)被
說明為 __pascal,因此產(chǎn)生了大寫函數(shù)名。這樣鏈接程序不會(huì)出錯(cuò)。
其他連接
http://blog.csdn.net/lotomer/archive/2006/06/28/844658.aspx
C++編程規(guī)范
利器在手,不要再徒手為之
C++語言所強(qiáng)制施行的構(gòu)造函數(shù)/析構(gòu)函數(shù)對(duì)稱反映了資源獲取/釋放函數(shù)對(duì),比如fopen/fclose, lock/unlock, new/delete, malloc/free的本質(zhì)的對(duì)稱性,這使得具有資源獲取的構(gòu)造函數(shù)和具有資源釋放的析構(gòu)函數(shù)的基于棧(或引用計(jì)數(shù))的對(duì)象成為了自動(dòng)化資源管理和清除的極佳工具
auto_ptr 實(shí)現(xiàn)代碼
auto_ptr實(shí)現(xiàn)代碼 (摘自<<More Effective c++>> Page 293)2006年09月11日 星期一 20:24template <class T>
class auto_ptr
{
public:
explicit auto_ptr(T*p = 0) : pointee(p){}
template<class U> auto_ptr(auto_ptr<U>& r);
~auto_ptr(){delete pointee;}
template<class U> auto_ptr<T>& operator=(auto_ptr<U>& r);
T& operator*() const {return *pointee;}
T* operator->() const {return pointee;}
T* get() const {return pointee;}
T* release(){
T* old = pointee;
pointee = 0;
return old;
}
void reset(T*p = 0){
if(pointee != p) {
delete pointee;
pointee = p;
}
}
private:
T* pointee;
template<class U> friend class auto_ptr<U>;
};
template<class T>
template<class U>
inline auto_ptr<T>::auto_ptr(auto_ptr<U>& r)
: pointee(r.release()) {}
template<class T>
template<class U>
inline auto_ptr<T>& operator=(auto_ptr<U>& r){
if(this != &r) reset(r.release());
return *this;
}
另外 SGI C++中的auto_ptr
/*
* Copyright (c) 1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*/
#ifndef __SGI_STL_MEMORY
#define __SGI_STL_MEMORY
#include <stl_algobase.h>
#include <stl_alloc.h>
#include <stl_construct.h>
#include <stl_tempbuf.h>
#include <stl_uninitialized.h>
#include <stl_raw_storage_iter.h>
#if defined(__STL_MEMBER_TEMPLATES)
__STL_BEGIN_NAMESPACE
template <class _Tp> class auto_ptr {
private:
_Tp* _M_ptr;
public:
typedef _Tp element_type;
explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
template <class _Tp1> auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW
: _M_ptr(__a.release()) {}
auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW {
if (&__a != this) {
delete _M_ptr;
_M_ptr = __a.release();
}
return *this;
}
template <class _Tp1>
auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW {
if (__a.get() != this->get()) {
delete _M_ptr;
_M_ptr = __a.release();
}
return *this;
}
~auto_ptr() __STL_NOTHROW { delete _M_ptr; }
_Tp& operator*() const __STL_NOTHROW {
return *_M_ptr;
}
_Tp* operator->() const __STL_NOTHROW {
return _M_ptr;
}
_Tp* get() const __STL_NOTHROW {
return _M_ptr;
}
_Tp* release() __STL_NOTHROW {
_Tp* __tmp = _M_ptr;
_M_ptr = 0;
return __tmp;
}
void reset(_Tp* __p = 0) __STL_NOTHROW {
delete _M_ptr;
_M_ptr = __p;
}
// According to the C++ standard, these conversions are required. Most
// present-day compilers, however, do not enforce that requirement---and,
// in fact, most present-day compilers do not support the language
// features that these conversions rely on.
#ifdef __SGI_STL_USE_AUTO_PTR_CONVERSIONS
private:
template<class _Tp1> struct auto_ptr_ref {
_Tp1* _M_ptr;
auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {}
};
public:
auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW
: _M_ptr(__ref._M_ptr) {}
template <class _Tp1> operator auto_ptr_ref<_Tp1>() __STL_NOTHROW
{ return auto_ptr_ref<_Tp>(this->release()); }
template <class _Tp1> operator auto_ptr<_Tp1>() __STL_NOTHROW
{ return auto_ptr<_Tp1>(this->release()); }
#endif /* __SGI_STL_USE_AUTO_PTR_CONVERSIONS */
};
__STL_END_NAMESPACE
#endif /* member templates */
#endif /* __SGI_STL_MEMORY */
// Local Variables:
// mode:C++
// End:
auto_ptr 注意事項(xiàng)
1.auto_ptr不能共享管理的指針的所有權(quán),并且指針是從堆上分配的
2.不能用于管理指針數(shù)組,因?yàn)樗谖鰳?gòu)的時(shí)候調(diào)用的是delete而不是delete[];并且c++類庫中還沒有具有auto_ptr語意學(xué)的指針數(shù)組。
3.auto_ptr是解決特殊問題的智能指針的一種,它和引入了引用記數(shù)的是智能指針是不一樣的,一般來講,根據(jù)auto_ptr的特性,應(yīng)用unconstant是一種不安全的做法。
4.它不能應(yīng)用容器中,因?yàn)檫@會(huì)涉及到copy以及assignment,這是不安全的,在語言以及庫中已經(jīng)做了預(yù)防,會(huì)在編譯時(shí)報(bào)錯(cuò)。
總體來說如果把a(bǔ)uto_ptr作為函數(shù)自變量或者返回值來用的話,就好像把函數(shù)內(nèi)棧上分配的空間地址返回,很不安全。