#include <iostream>
#include <memory>
class test
{
private:
int x , y;
public:
test(int a , int b):x(a),y(b){}
void fun()
{
std::cout<< x<<" "<<y<<" "<<std::endl;
}
};
void show(std::auto_ptr<test> t1)
{
t1->fun();
}
int main()
{
show(new test(3,4));
}
我收到编译错误,请告诉我这段代码有什么问题?提前致谢。
答案 0 :(得分:3)
每当动态分配对象时,您应该创建一个名为的智能指针,该指针立即取得对象的所有权,然后使用该命名的智能指针。例如,
std::auto_ptr<test> ptr(new test(3, 4));
show(ptr);
您无法直接将new test(3, 4)
传递给函数,因为必须显式构造std::auto_ptr
个对象;如果智能指针隐含地拥有对象的所有权,那将是非常意外的。
也就是说,这是相当不寻常的,因为当你致电show()
时,auto_ptr
被复制,当auto_ptr
被“复制”时,原件失去所有权并且副本获得所有权(因此,在调用show()
后,您会发现ptr
不再拥有该对象的所有权。
答案 1 :(得分:0)
詹姆斯解释了如何解决这个问题。
但是auto_ptr的设计原因是你不能这样做:
show(new test(3,4));
是因为这是一个坏主意 即使这样(如果允许的话):
show(std::auto_ptr<test>(new test(3,4)));
这是一个坏主意。
所以你问为什么。
在正常情况下,没什么大不了的 当你有一个带有多个参数的函数时会发生什么。
show2(std::auto_ptr<test>(new test(3,4)), SomeObject());
现在标准保证在调用之前将完全评估所有参数(甚至构建auto_ptr)。但它不保证评估顺序,也不保证评估不会交错。
因此可以进行评估:
// Phsedu code for parameter evaluation
test* tmp1 = new test(3,4);
SomeObject const& tmp2 = SomeObject();
std::auto_ptr<test> const& tmp3(tmp1);
call(tmp3, tmp1)
这个订单很糟糕。因为如果SomeObject的构造函数抛出异常,您将泄漏tmp1,因为它尚未分配给std :: auto_ptr。
这就是为什么我们设计auto_ptr以便你必须给它一个命名变量。
std::auto_ptr<test> tmp3(new test(3,4));
SomeObject tmp1;
call(tmp3, tmp1)
现在,如果SomObject构造函数抛出,测试对象将被整理。