zoukankan      html  css  js  c++  java
  • C++之auto_ptr

    C++之auto_ptr】 

    std::auto_ptr

    std::auto_ptr 属于 STL,当然在 namespace std 中,包含头文件 #include<memory> 便可以使用。std::auto_ptr 能够方便的管理单个堆内存对象。

    我们从代码开始分析:

    void TestAutoPtr() {

    std::auto_ptr<Simple> my_memory(new Simple(1));   // 创建对象,输出:Simple:1

    if (my_memory.get()) {                            // 判断智能指针是否为空

    my_memory->PrintSomething();                    // 使用 operator-> 调用智能指针对象中的函数

    my_memory.get()->info_extend = "Addition";      // 使用 get() 返回裸指针,然后给内部对象赋值

    my_memory->PrintSomething();                    // 再次打印,表明上述赋值成功

    (*my_memory).info_extend += " other";           // 使用 operator* 返回智能指针内部对象,然后用“.”调用智能指针对象中的函数

    my_memory->PrintSomething();                    // 再次打印,表明上述赋值成功

      }

    }                                                   // my_memory 栈对象即将结束生命期,析构堆对象 Simple(1)

    执行结果为:

    Simple: 1

    PrintSomething:

    PrintSomething: Addition

    PrintSomething: Addition other

    ~Simple: 1

    上述为正常使用 std::auto_ptr 的代码,一切似乎都良好,无论如何不用我们显示使用该死的 delete 了。

    其实好景不长,我们看看如下的另一个例子:

    void TestAutoPtr2() {

      std::auto_ptr<Simple> my_memory(new Simple(1));

      if (my_memory.get()) {

        std::auto_ptr<Simple> my_memory2;   // 创建一个新的 my_memory2 对象

        my_memory2 = my_memory;             // 复制旧的 my_memory 给 my_memory2

        my_memory2->PrintSomething();       // 输出信息,复制成功

        my_memory->PrintSomething();        // 崩溃

      }

    }

    最终如上代码导致崩溃,如上代码时绝对符合 C++ 编程思想的,居然崩溃了,跟进 std::auto_ptr 的源码后,我们看到,罪魁祸首是“my_memory2 = my_memory”,这行代码,my_memory2 完全夺取了 my_memory 的内存管理所有权,导致 my_memory 悬空,最后使用时导致崩溃。

    所以,使用 std::auto_ptr 时,绝对不能使用“operator=”操作符。作为一个库,不允许用户使用,确没有明确拒绝[1],多少会觉得有点出乎预料。

    看完 std::auto_ptr 好景不长的第一个例子后,让我们再来看一个:

    void TestAutoPtr3() {

      std::auto_ptr<Simple> my_memory(new Simple(1));

      if (my_memory.get()) {

        my_memory.release();

      }

    }

    执行结果为:

    Simple: 1

    看到什么异常了吗?我们创建出来的对象没有被析构,没有输出“~Simple: 1”,导致内存泄露。当我们不想让 my_memory 继续生存下去,我们调用 release() 函数释放内存,结果却导致内存泄露(在内存受限系统中,如果my_memory占用太多内存,我们会考虑在使用完成后,立刻归还,而不是等到 my_memory 结束生命期后才归还)。

    正确的代码应该为:

    void TestAutoPtr3() {

      std::auto_ptr<Simple> my_memory(new Simple(1));

      if (my_memory.get()) {

        Simple* temp_memory = my_memory.release();

        delete temp_memory;

      }

    }

    void TestAutoPtr3() {

      std::auto_ptr<Simple> my_memory(new Simple(1));

      if (my_memory.get()) {

        my_memory.reset();  // 释放 my_memory 内部管理的内存

      }

    }

    原来 std::auto_ptr 的 release() 函数只是让出内存所有权,这显然也不符合 C++ 编程思想。

    总结:std::auto_ptr 可用来管理单个对象的对内存,但是,请注意如下几点:

    (1)    尽量不要使用“operator=”。如果使用了,请不要再使用先前对象。

    (2)    记住 release() 函数不会释放对象,仅仅归还所有权。

    (3)    std::auto_ptr 最好不要当成参数传递(读者可以自行写代码确定为什么不能)。

    (4)    由于 std::auto_ptr 的“operator=”问题,有其管理的对象不能放入 std::vector 等容器中。

    (5)    ……

    使用一个 std::auto_ptr 的限制还真多,还不能用来管理堆内存数组,这应该是你目前在想的事情吧,我也觉得限制挺多的,哪天一个不小心,就导致问题了。

    由于 std::auto_ptr 引发了诸多问题,一些设计并不是非常符合 C++ 编程思想,所以引发了下面 boost 的智能指针,boost 智能指针可以解决如上问题。

  • 相关阅读:
    Software Solutions CACHE COHERENCE AND THE MESI PROTOCOL
    CACHE COHERENCE AND THE MESI PROTOCOL
    Multiprocessor Operating System Design Considerations SYMMETRIC MULTIPROCESSORS
    Organization SYMMETRIC MULTIPROCESSORS
    PARALLEL PROCESSING
    1分钟内发送差评邮件
    Secure Digital
    SYMMETRIC MULTIPROCESSORS
    A Taxonomy of Parallel Processor Architectures
    parallelism
  • 原文地址:https://www.cnblogs.com/tekkaman/p/2951521.html
Copyright © 2011-2022 走看看