【发布时间】:2009-04-29 15:02:20
【问题描述】:
如果我有一个 auto_ptr,我可以传递它以供参考吗?喜欢:
auto_ptr<MyClass>Class(new MyClass);
void SetOponent(MyClass& oponent);
//So I pass SetOponent(Class)
什么是 auto_ptrs 的奇数复制行为?
【问题讨论】:
-
不知道为什么这是社区维基...
如果我有一个 auto_ptr,我可以传递它以供参考吗?喜欢:
auto_ptr<MyClass>Class(new MyClass);
void SetOponent(MyClass& oponent);
//So I pass SetOponent(Class)
什么是 auto_ptrs 的奇数复制行为?
【问题讨论】:
不,你不能,你必须取消引用它:
SetOponent( * Class )
至于复制行为,我建议您阅读一本关于 C++ 的好书,例如 Scott Meyers 的《Effective C++》。 auto_ptr 的复制行为非常不直观,可能超出了 SO 答案的范围。然而,什么都没有冒险......
复制 auto_ptr 时,所有权从原件转移到副本。例如:
auto_ptr <Foo> p1( new Foo );
此时 p1 拥有指向 Foo 对象的指针。
auto_ptr <Foo> p2( p1 );
复制后,p2 拥有指针,p1 被更改,因此它现在拥有一个 NULL 指针。这很重要,因为在 C++ 中的很多地方都发生了复制。例如,您不应该将 auto_ptrs 按值传递给函数,或尝试将它们存储在标准库容器中。
【讨论】:
奇怪的复制行为是您无法在制作副本的同时保留原件。为此,请使用 shared_ptr(在 boost:: 或 std::tr1:: 中)。这意味着您不能拥有auto_ptrs 的STL 容器等。 auto_ptr<> 在您将拥有一个对象的一个副本且生命周期有限时非常有用。如果您复制到另一个auto_ptr<>,您将丢失第一个。如果你传递了指针,你很有可能尝试使用一个已经被删除的对象。
如果你愿意,你可以调用SetOponent(*Class);,因为这将传递实际的项目(你传递对象,而不是指针,引用)。如果你传递给一个指针,你可以用SetOpponent(Class.get()) 调用。当 Class 超出范围时,您仍然会遇到 MyClass 将被删除的问题。
【讨论】: