auto_ptr_ref和auto_ptr的關係 (轉)

amyz發表於2007-08-14
auto_ptr_ref和auto_ptr的關係 (轉)[@more@] 

auto_ptr_refauto_ptr的關係:namespace prefix = o ns = "urn:schemas--com::office" />

 

這是C++新聞組上一篇文章。它很好的解釋了auto_ptr_ref和auto_ptr的之間的關係。

你可以在上查詢 “auto_ptr_ref - anyone know what it's about?”這個主題。

此文章有刪節。

 

1 問:

對ANSI/ISO C++標準,我有兩個問題,關於  auto_ptr的幫助類auto_ptr_ref。

1)這個類的意圖是什麼。

2) 它怎樣工作。

 

2 答:

1)

在最初的提議中,'auto_ptr'的語義被打破,是因為這個型別的'const'的情況。

最初的建議是有一個以'const&'作為引數的複製構造。,然而,這會導致一些驚人

之事。,例如:

//這僅僅是為了體現原是的意圖。它不是一個標準的版本。

void f(std::auto_ptr const& ap) {

std::auto_ptr (ap);

// ...

}

int main() {

std::auto_ptr const ai(new int(17));

f(ai);

// s! 'ai' 不在擁有一個指標。 再次說明,這不是標準版本的行為。

}

基本上,這樣的規則破壞了一個帶有'const&'的複製建構函式。甚至於有其他做法會帶來

更壞的結果。最後,主要是法國代表團他們想要一個這樣地'auto_ptr',

-沒有帶'autor_ptr'作為引數地複製建構函式。

-允許'std::auto_ptr ap(f());'這樣地用法。在這裡,'f()'返回一個

'std::auto_ptr'.

...或者,為了c++標準,把'auto_ptr'應該從標準中被剔除得到了法國的贊成票,一些其他

國家一定程度上也有類似的想法。所以,Greg和Bill提出了'auto_ptr_ref'的想法,這樣所有的一切都變得美好了。在他們的第一次陳述中,每個人都很驚奇於這個竟然能夠工作。但是它能,並且所有的一切都很好。

2) 它怎樣工作?

它所做的事情是,它使的從一個臨時量(例如,從一個函式返回)透過一個不帶'const&'做參

數的複製建構函式來構造一個'auto_ptr'物件成為可能。問題是,你不能傳遞一個臨時變數

到一個帶'&'的函式(也就是說,一個非常量的引用(non-const reference))作為引數。即

使它不是一個建構函式。並且你不能透過值傳遞來定義一個複製建構函式,因為這裡也需要一

個複製建構函式。所以,這個是怎樣完成的呢?

 

竅門是透過兩個的定義轉換,也就是從'auto_ptr' 到 'auto_ptr_ref'再到'auto_ptr'。

正常的第一反應是“但是這裡只有一個使用者定義的轉換呀”,這是完全正確的並且也能被

'auto_ptr'所掌握。所以,這個怎樣工作呢?,好,再這個處理中,兩個物件被構造,也

就是說一個臨時量被當作函式和一個'auto_ptr'的結果。關於臨時量的型別沒有什麼好說

的,竅門是:從一個'auto_ptr'的返回的被放在堆疊上的臨時量,它不是一個'auto_ptr'

而是一個'auto_ptr_ref'(的表示是:對於使用者來說這個看上去象任何其他函式返回

一個物件).這是明白無誤的,因為有一個使用者定義的從'auto_ptr' to 'auto_ptr_ref'的

轉換。現在,在堆疊上有一個'auto_ptr_ref'而不是'auto_ptr'需要被構造。這是很容易

的,因為有一個'auto_ptr'建構函式,引數是'auto_ptr_ref'型別的物件。這個就是第二

個轉換,但是再這一點上使用者只僅僅定義了一個轉換引數。這就是它的全部。我省略了一些

關於當維護指標的所有權被轉移給別人的細節,但是這個僅僅做一些薄記工作就行了。我們

感興趣的部分是兩個轉換是為什麼'auto_ptr_ref'要被引進的原因的。Greg 和 Bill的實現

真是cool。

 

 

//譯者:

//這個是在上的,我僅僅

//列出它。

 

#include

 

class auto_ptr

{

private:

struct auto_ptr_ref { };

 

public:

auto_ptr() { cout << "auto_ptr::auto_ptr() "; }

auto_ptr(auto_ptr&) { cout << "auto_ptr::auto_ptr(auto_ptr&) "; }

operator auto_ptr_ref()

{ cout << "auto_ptr::operator auto_ptr_ref() "; }

auto_ptr(auto_ptr_ref) { cout <<

"auto_ptr::auto_ptr(auto_ptr_ref) "; }

~auto_ptr() { cout << "auto_ptr::~auto_ptr() "; }

};

 

 

auto_ptr function1();

auto_ptr function2();

 

 

int main()

{

auto_ptr f1=function1(); // calls function function1(), see below now

// looks for "auto_ptr::auto_ptr(const auto_ptr&)", not found

// can't use "auto_ptr::auto_ptr(auto_ptr&)"

// because return value of 'function1()' is a temporary

// so consr two-step routes now

// 1) use "auto_ptr::operator auto_ptr_ref()"

// 2) use "auto_ptr::auto_ptr(auto_ptr_ref)" to construct 'f1'

// call to "auto_ptr::~auto_ptr()" to destroy return of 'function1()'

 

cout << "after1 ";

 

auto_ptr f2=function2(); // figure this one out yourself

cout << "after2 ";

 

} // 2 calls to "auto_ptr::~auto_ptr()" to destroy 'f1' and 'f2'

 

 

auto_ptr function1() // comments assume no return value optimization

{

auto_ptr a; // call to "auto_ptr::auto_ptr()"

return a; // call to "auto_ptr::auto_ptr(auto_ptr&)"

} // call to "auto_ptr::~auto_ptr()" to destroy 'a'

 

auto_ptr function2() // figure this one out yourself, uses auto_ptr_ref

{

return auto_ptr();

}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-956335/,如需轉載,請註明出處,否則將追究法律責任。

相關文章