<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                之前博客《[淺析C++中的智能指針](http://blog.csdn.net/wangshubo1989/article/details/48337955 "智能指針")》講訴了一些智能指針的東西,可以幫助我們更加方便高效的使用指針,但是凡事都不會很完美。即使你使用智能指針代替了傳統的指針,在實戰中你還是會遇到很多的坑兒。 現在,就分幾個方面: 首先為了簡化代碼,進行了一些定義: ~~~ class Test { public: Test():m_value(0) { std::cout << "Test::Test" << std::endl; } ~Test() { std::cout << "Test::~Test destructor" << std::endl; } int m_value; }; typedef std::auto_ptr<Test> TestAutoPtr; typedef std::unique_ptr<Test> TestUniquePtr; typedef std::shared_ptr<Test> TestSharedPtr; ~~~ **為什么auto_ptr 被棄用?** auto_ptr 是第一個智能指針。 但是為什么會被棄用呢?看看一個簡單的例子 ~~~ void doSomethig(TestAutoPtr myPtr) { myPtr->m_value = 11; } void AutoPtrTest() { TestAutoPtr myTest(new Test()); doSomethig(myTest); myTest->m_value = 10; } ~~~ 編譯上面的代碼并試著運行,會有什么樣的結果呢?答案是在doSomething執行結束后程序崩潰! 我們可以推斷,在doSomething 中,引用計數增加了,但是auto_ptr沒有這樣的功能。 所以我們應該傳遞智能指針的引用。但是對于更加復雜的對象,我們就會失去控制。 **為什么 unique_ptr 很好用?** 幸運的是,我們有新的智能指針。在之前的例子中,我們使用std::unique_ptr 代替auto_ptr 這時候,我們會得到編譯錯誤,而不是運行時期的錯誤。因為,我們不能傳遞一個unique_ptr給另一個函數。 但是為了可以傳遞,我們可以使用move把智能指針的所有權進行轉移,代碼如下: ~~~ doSomethig(std::move(myTest)); ~~~ **如何使用數組和unique_ptr 聯系在一起?** 首先我們要明確的是,下面的代碼是致命的: ~~~ std::unique_ptr<int> p(new int[10]); // will not work! ~~~ 之所以說上面的代碼是致命的是因為可以編譯通過。但是當資源被釋放掉的時候,只有delete被調用,而不是delete[]。所以,我們如何確保delete[] 被調用呢? 你應該這么干: ~~~ std::unique_ptr<int[]> p(new int[10]); p[0] = 10; ~~~ 對于上面的例子,我們可以這么干: ~~~ std::unique_ptr<Test[]> tests(new Test[3]); ~~~ 這樣就會得到我們期望的輸出: Test::Test Test::Test Test::Test Test::~Test destructor Test::~Test destructor Test::~Test destructor **為什么使用shared_ptr ?** 通過引用計數來實現shared_ptr ,所以我們這么干: ~~~ std::shared_ptr<Test> sp(new Test()); std::shared_ptr<Test> sp2 = std::make_shared<Test>(); ~~~ 得到這樣的輸出: Test::Test Test::Test Test::~Test destructor Test::~Test destructor **如何使用數組和shared_ptr 聯系在一起?** ~~~ std::shared_ptr<Test> sp(new Test[2], [](Test *p) { delete [] p; }); ~~~ **如何把智能指針傳遞給函數?** 看代碼: ~~~ void testSharedFunc(std::shared_ptr<Test> sp) { sp->m_value = 10; } void testSharedFuncRef(const std::shared_ptr<Test> &sp) { sp->m_value = 10; } void SharedPtrParamTest() { std::shared_ptr<Test> sp = std::make_shared<Test>(); testSharedFunc(sp); testSharedFuncRef(sp); } ~~~ 只有testSharedFunc 會增加引用計數。 也就是說傳遞ref沒有增加引用計數,那么到底是哪種方式好呢? 視情況而定! **如何對智能指針進行類型轉換?** 看看這個代碼: ~~~ class BaseA { protected: int a{ 0 }; public: virtual ~BaseA() { } void A(int p) { a = p; } }; class ChildB : public BaseA { private: int b{ 0 }; public: void B(int p) { b = p; } }; ~~~ 毫無疑問,我可以創建一個指向A的智能指針,并初始化為B: ~~~ std::shared_ptr<BaseA> ptrBase = std::make_shared<ChildB>(); ptrBase->A(10); ~~~ 但是如何強制轉換呢,把ptrBase指向B呢?你可能這樣嘗試: ~~~ ChildB *ptrMan = dynamic_cast<ChildB *>(ptrBase.get()); ptrMan->B(10); ~~~ 成功了,但是代價是你只獲得了一個普通指針。智能指針的引用計數并沒有增加。所以更好的辦法就是使用智能指針的轉換方法: ~~~ std::shared_ptr<ChildB> ptrChild = std::dynamic_pointer_cast<ChildB>(ptrBase); if (ptrChild) { ptrChild->B(20); std::cout << "use count A: " << ptrBase.use_count() << std::endl; std::cout << "use count B: " << ptrChild.use_count() << std::endl; } ~~~ 通過使用std::dynamic_pointer_cast 你會得到一個shared pointer. **結語:** 智能指針沒有用,但是我們應該更加謹慎的使用它們! stay foolish stay hungry!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看