C++ 使用std::auto_ptr的意义
什么是C++ 使用std::auto_ptr的意义,c++,pointers,smart-pointers,auto-ptr,C++,Pointers,Smart Pointers,Auto Ptr,什么是auto_ptr? 请看以下代码: #include <iostream> #include <memory> class A { public: ~A() { std::cout << "DEST"; }; }; void func(A* pa) { std::cout << "A pointer"; } void test() { A a; std::auto_ptr&
auto_ptr
?
请看以下代码:
#include <iostream>
#include <memory>
class A
{
public:
~A()
{
std::cout << "DEST";
};
};
void func(A* pa)
{
std::cout << "A pointer";
}
void test()
{
A a;
std::auto_ptr<A> pA(new A);
//func(pA); //compiler error here cannot convert parameter 1 from 'std::auto_ptr<_Ty>' to 'A *'
std::cout << "end";
}
int main(int argc, char* argv[])
{
test();
return 0;
}
#包括
#包括
甲级
{
公众:
~A()
{
std::cout如果您能够在堆栈上创建所有对象,那么就不需要使用auto_ptr
- 从函数返回对象(不能返回本地对象)
- 确保从函数返回的对象要么被调用方接收,要么在出现异常时被销毁
- 聚合指向类内对象的指针(您需要确保析构函数将其删除,或者只需将其设置为防止内存泄漏的
自动\u ptr
,句号)
- ……还有更多
再想一想,你可能应该这样做。他知道的比我多。-这是正确的做法:
void test()
{
A a;
std::auto_ptr<A> pA(new A);
func(pA.get());
std::cout << "end";
}
void测试()
{
A A;
标准:自动ptr pA(新A);
func(pA.get());
标准::cout
唯一的想法是我不必写删除
是的,考虑到内存泄漏是您将遇到的最常见的错误之一,这是一个相当大的好处
指针的意义是什么?当我离开作用域时,它是否会被破坏。我使用指针来控制变量的活动
你改变了这种想法,用作用域来定义变量的寿命。你只需在适当的作用域中声明这些东西,就不必再担心清理问题了。这就是关键所在
您的示例是精心设计的,但您仍然可以看到它的价值所在。当然,您可能不会忘记在一个完全不起作用的两行函数中调用delete
。在实际应用程序中,事情会变得更加复杂
<> >当你<代码>新< /代码>一堆对象时,你可以依赖于一个事实:当函数退出时,对象将被清理。类也一样。当一个实例超出范围时,你可以依靠它的析构函数来为你分配内存。考虑在抛出异常时会发生什么。r您需要确保处理每一个可能的异常和每一个可能的返回路径,以确保您自己完成清理
还有
普通变量initialize位于堆栈上,指针位于堆上
不完全正确。本例中的指针具有自动存储持续时间,但它所指向的没有
编译器对您传递auto\u ptr
发出吠声的原因是函数没有采用auto\u ptr
。您需要调用get()
来传递指针本身
<>你说,你不应该使用<代码> AutoPPTR <代码>;如果你有一个C++的0x编译器,你应该使用它。< P>有很多理由使用<代码> AutoPyTrp>代码>(或其他智能指针)来管理内存。
void test()
{
A a;
std::auto_ptr<A> pA(new A);
if(SomeFunc())
return;
//func(pA); //compiler error here cannot convert parameter 1 from 'std::auto_ptr<_Ty>' to 'A *'
std::cout << "end";
}
pA
对象仍然拥有内存;func
不能删除它,也不能存储它。重要信息
请记住,std::auto_ptr
有许多缺点,如果编译器提供,通常应该使用std::unique_ptr
。(如果没有,请更新编译器!)
现在回到你的问题
使用这个auto_ptr有什么意义?当它作为普通的类初始化变量(a)离开作用域时,它调用类析构函数
没错。auto_ptr
的原因是强制执行严格的所有权语义,这样当指针本身被销毁时,对象就被正确地销毁了
我无法将此指针传递给具有类指针(func)的函数
可以,您需要使用get()
来查找原始指针。将指针传递到函数调用时使用get()
意味着函数不会拥有该对象的所有权(该auto_ptr
仍然拥有该对象,并期望该对象在函数返回后仍然有效)
或者,您可以在指针上使用release()
,以获取原始指针,并指示auto_ptr
不再负责对象的所有权
我不能对[]或char[]使用指针auto_ptr,因为auto_ptr调用delete not delete[]
是的,这是一个问题。这就是为什么自从引入了独特的ptr
后不再使用自动ptr
的原因之一。它做同样的事情,但更安全(=更容易)使用,更通用
唯一的想法是我不必写delete,但是如果指针在我超出范围时被破坏,它的意义又是什么呢
这样您就不会忘记它:-)或者您可以使用auto\u ptr
(或者更好的unique\u ptr
作为类对象中的成员)
但是,请告诉我使用auto_ptr而不是普通指针的意义是什么
长话短说:许多指针可以指向单个对象。存在各种智能指针,它们使用类型系统记账,由哪个指针拥有对象(=负责释放对象)。
旁注
如果您有一个类(可能)拥有另一个对象的实例,只需编写:
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) { ptr.reset(ptr); }
// ...
std::unique_ptr<Type> ptr;
};
<>同样的行为?不!因为现在有了安全的C++代码,当代码< > x>代码>被破坏时,你还需要编写一个析构函数来删除<代码> PTR < /代码>。
现在好了吗?不!因为您有一个公共析构函数,所以需要上卷(或阻止)您自己的复制构造函数和赋值运算符,因为否则您可能会得到两个指向同一类型对象的X实例,而这两个实例在这里都认为自己拥有此实例,并且有时都会尝试删除它。Boom,access违例
Unique_ptr不允许您隐式复制X对象以及对ptr
的强引用,因为Unique_ptr是不可复制的(它认为它是
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) { ptr.reset(ptr); }
// ...
std::unique_ptr<Type> ptr;
};
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) {delete ptr; ptr = ptr2;}
// ...
Type* ptr;
};