[英]C++ auto_ptr in functions (as argument and return value)
我試圖在我的代碼中使用auto_ptr,但顯然出了問題。
auto_ptr<ClassType> Class(s.Build(aFilename)); //Instantiation of the Class object
int vM = s.GetM(Class);
int vS = s.Draw(Class);
奇怪的是,在實例化Class之后,Class對象存在,因此通過調用s.GetModelMean(Class),Class不為空。 但退出函數GetM后,Class為空,因此不再可用。 調用Draw函數時發生崩潰。
我按以下方式聲明了這些函數:
int GetM(auto_ptr<ClassType> aM);
似乎班級被摧毀了,但我不明白為什么......
你不要給auto_ptr作為函數的參數。 要么:
int GetM(const auto_ptr<ClassType>&)
要么
int GetM(ClassType&)
要么
int GetM(ClassType*)
(也可能與const - 取決於你正在做什么)。 第一個你會用同樣的方式調用,第二個函數你會這樣調用:
int vM = s.GetM(*Class.get())
沒有明星的最后一個。
原因是:GetM將復制auto_ptr(而不是Class對象)並在返回時銷毀auto_ptr。 auto_ptr(它是作用域指針或唯一指針 - 不是引用計數器!)將破壞Class。
無論如何:auto_ptr非常破碎。 只要有可能(您的編譯器已經支持C ++ 11的一些小部分),請使用std :: unique_ptr和std :: shared_ptr(最后一個引用計數)。 unique_ptr不允許你像那樣亂用它(因為不允許復制它 - 這更有意義)。
auto_ptr有一個“神奇的”復制構造函數,它與源對象混淆。 通過按值將參數傳遞給函數,可以觸發對復制構造函數的調用,並將原始auto_ptr保留為不指向任何內容的狀態。
打電話的原因
int GetM(auto_ptr<ClassType> aM);
析構給定的對象是auto_ptr
在復制對象時有一個相當令人驚訝的行為; 它不僅修改了目標對象,還修改了源對象。 如果你這樣做的話
std::auto_ptr<int> y = x; // modifies x *and* y
存儲在x
的指針移動到y
( x
設置為null)。
這意味着std::auto_ptr
非常不適合傳遞值或將它們存儲在容器中(因為容器傾向於在內部復制對象)。 在退出某個范圍時,確保某些對象被銷毀是合適的 - 例如,使代碼異常安全。 所以有類似的東西
void f() {
std::auto_ptr<int> x = new int;
...
// no need to delete anything, destroying 'x' will delete
}
要么
class Widget {
public:
Widget() : m_myData( new int ) { }
private:
Widget(const Widget &other); // disabled
void operator=( const Widget &other ); // disabled
std::auto_ptr<int> m_myData;
};
實際上很好,可以簡化代碼。
擁有std::auto_ptr
意味着擁有所有權。 因此,在您的特定情況下,我建議調整GetM
簽名,以便它采用普通指針。
auto_ptr
使用一個小技巧,這樣每當你“復制”A到B時,B得到對象,A被清除。 您可以使用它來非常清楚地聲明所有權傳遞語義(來源:Scott Meyers和Andrei Alexandrescus書籍。順便說一句,如果您想了解更多,請閱讀Effective C ++)。
當然,如果可能的話,你應該使用unique_ptr
(你可以把它放在向量中!)來自C ++ 0x或來自Boost而不是auto_ptr
,因為不推薦使用auto_ptr
。
如果您對技巧細節感興趣,請知道沒有魔術復制構造函數。 根本沒有復制構造函數。 復制構造函數采用const引用,您將無法清除復制的對象。 所以當你寫作
std::auto_ptr<A> a1(new A);
std::auto_ptr<A> a2(a1);
a1首先被轉換為一些臨時對象。 轉換運算符采用非const引用並清除a1。 然后a2由此臨時對象初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.