Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c++;auto#ptr与托管指针相关(Java、C#……) 我来自一个管理的世界,C++的自动内存管理对我来说不太清楚。_C#_Java_C++_Managed_Auto Ptr - Fatal编程技术网

c++;auto#ptr与托管指针相关(Java、C#……) 我来自一个管理的世界,C++的自动内存管理对我来说不太清楚。

c++;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

如果理解正确,我会将指针封装在堆栈对象中,当auto_ptr超出范围时,它会自动调用指向的对象上的delete


我应该如何使用它,以及如何自然地避免固有的C++问题?< /P> < P>是的,<代码> STD::AutoMyPTR < /C>在其超出范围时调用其内容<代码>删除>代码>。只有在没有共享所有权的情况下,才能使用

auto_ptr

auto_ptr
不是特别灵活,您不能将其用于使用
new[]
或任何其他方法创建的对象

共享所有权通常是通过共享指针来实现的,例如,具有的实现。最常见的用法(例如在Boosts
shared\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 ...