c++;auto#ptr与托管指针相关(Java、C#……) 我来自一个管理的世界,C++的自动内存管理对我来说不太清楚。
如果理解正确,我会将指针封装在堆栈对象中,当auto_ptr超出范围时,它会自动调用指向的对象上的deletec++;auto#ptr与托管指针相关(Java、C#……) 我来自一个管理的世界,C++的自动内存管理对我来说不太清楚。,c#,java,c++,managed,auto-ptr,C#,Java,C++,Managed,Auto Ptr,如果理解正确,我会将指针封装在堆栈对象中,当auto_ptr超出范围时,它会自动调用指向的对象上的delete 我应该如何使用它,以及如何自然地避免固有的C++问题?< /P> < P>是的, STD::AutoMyPTR < /C>在其超出范围时调用其内容删除>代码>。只有在没有共享所有权的情况下,才能使用auto_ptr。 auto_ptr不是特别灵活,您不能将其用于使用new[]或任何其他方法创建的对象 共享所有权通常是通过共享指针来实现的,例如,具有的实现。最常见的用法(例如在Boost
我应该如何使用它,以及如何自然地避免固有的C++问题?< /P> < P>是的,<代码> STD::AutoMyPTR < /C>在其超出范围时调用其内容<代码>删除>代码>。只有在没有共享所有权的情况下,才能使用
auto_ptr
。auto_ptr
不是特别灵活,您不能将其用于使用new[]
或任何其他方法创建的对象
共享所有权通常是通过共享指针来实现的,例如,具有的实现。最常见的用法(例如在Boostsshared\u ptr
中实现)采用一种方案,并在最后一个智能指针超出范围时清除指针对象。shared\u ptr
有一个很大的优势——它允许您指定自定义的删除程序。因此,你可以基本上把所有的资源都放进去,只需指定它应该使用的DELTER。 < P> <代码> AutoPytTr>代码>是C++中最简单的实现。您的理解是正确的,只要调用它的析构函数,底层指针就会得到delete
d
这是C语言的一个进步,在C语言中没有析构函数,任何有意义的RAII都是不可能的
迈向automagic内存管理的下一步是。它使用引用计数来跟踪对象是否处于活动状态。这使得程序员可以更自由地创建对象,但仍然不如Java和C#中的垃圾收集功能强大。这种方法失败的一个例子是循环引用。如果A有一个指向B的ref计数指针,而B有一个指向A的ref计数指针,那么它们将永远不会被破坏,即使没有其他对象正在使用它们
现代面向对象的语言使用某种形式的语言变体。这种技术允许管理循环引用,并且对于大多数编程任务来说足够可靠。以下是如何使用智能指针。举个例子,我将使用一个
shared\u ptr
{
shared_ptr<Foo> foo(new Foo);
// do things with foo
}
// foo's value is released here
{
共享_ptr foo(新foo);
//用foo做事
}
//foo的值在这里发布
几乎所有智能指针的目标都与上述类似,即智能指针中的对象在智能指针作用域的末尾被释放。但是,有三种类型的智能指针被广泛使用,它们在如何处理所有权方面具有非常不同的语义:
shared_ptr
使用“共享所有权”:shared_ptr
可以由多个作用域/对象持有,并且它们都拥有对该对象的引用。当最后一个参照脱落时,对象将被删除。这是使用引用计数完成的auto_ptr
使用“可转让所有权”:auto_ptr
的值只能保留在一个地方,并且每次分配auto_ptr
时,受让人接收到对象的所有权,转让人失去对对象的引用。如果退出了一个auto_ptr
的作用域,而没有将对象转移到另一个auto_ptr
,则该对象将被删除。因为一次只有一个对象的所有者,所以不需要引用计数unique_ptr
/scoped_ptr
使用“不可转让所有权”:对象仅在其创建地持有,不能转移到其他地方。当程序离开创建unique_ptr
的作用域时,该对象将被删除,不会提出任何问题我承认这是一件很难接受的事,但我希望这一切很快就会被接受。希望有帮助 您应该使用
boost::shared\u ptr
而不是std::auto\u ptr
auto_ptr
和shared_ptr
只保留指针的一个实例,因为它们是本地堆栈对象,所以在超出范围时会被释放。一旦释放它们,它们就在内部指针上调用delete
举个简单的例子,实际的shared_ptr
和auto_ptr
更复杂(它们有分配和转换/访问内部指针的方法):
与其试图理解
auto_ptr
及其与垃圾收集引用的关系,不如真正尝试了解底层模式:
C++中,所有局部对象在它们超出范围时都调用它们的析构函数。这可以用来清理内存。例如,我们可以编写一个类,在它的构造函数中,给它一个指向堆分配内存的指针,并在它的析构函数中释放这个指针
这正是auto_ptr
所做的。(不幸的是,auto_ptr
在赋值和复制方面也有一些众所周知的古怪语义)
这也是boost::shared_ptr
或其他智能指针所做的。这些都没有魔力。它们只是在构造函数中给定指针的类,并且,由于它们通常在堆栈上分配,它们会在某个点自动超出范围,因此调用它们的析构函数,它可以删除最初传递给构造函数的指针。你可以自己编写这样的类。同样,没有什么神奇之处,只是C++生命周期规则的简单应用:当一个局部对象超出范围时,它的析构函数被调用
许多其他的类去掉了中间人,只是让同一类同时进行分配和解除分配。例如,std::vector
根据需要调用new
,以创建其内部数组——并在其析构函数中调用delete
以释放它
复制向量时,它会注意分配一个新数组
template <typename T>
struct myshrdptr
{
T * t;
myshrdptr(T * p) : t(p) {}
~myshrdptr()
{
cout << "myshrdptr deallocated" << endl;
delete t;
}
T * operator->() { return t; }
};
struct AB
{
void dump() { cout << "AB" << endl; }
};
void testShrdptr()
{
myshrdptr<AB> ab(new AB());
ab->dump();
// ab out of scope destructor called
// which calls delete on the internal pointer
// which deletes the AB object
}
int main()
{
testShrdptr();
cout << "done ..." << endl;
}
AB
myshrdptr deallocated
done ...