[英]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.