最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中的循環(huán)引用

 更新時間:2017年09月12日 08:52:36   作者:D_Guco  
雖然C++11引入了智能指針的,但是開發(fā)人員在與內(nèi)存的斗爭問題上并沒有解放,如果我門實用不當(dāng)仍然有內(nèi)存泄漏問題,其中智能指針的循環(huán)引用缺陷是最大的問題。下面通過實例代碼給大家介紹c++中的循環(huán)引用,一起看看吧

雖然C++11引入了智能指針的,但是開發(fā)人員在與內(nèi)存的斗爭問題上并沒有解放,如果我門實用不當(dāng)仍然有內(nèi)存泄漏問題,其中智能指針的循環(huán)引用缺陷是最大的問題。

//
// main.cpp
// test
//
// Created by 杜國超 on 17/9/9.
// Copyright © 2017年 杜國超. All rights reserved.
//
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class CObjB;
class CObjA
{
public:
  CObjA() { cout << "CObjA Constructor..." << endl; }
  ~CObjA() { cout << "CObjA Destructor..." << endl; }
  shared_ptr<CObjB> m_pb; // 在A中引用B
};
class CObjB
{
public:
  CObjB() { cout << "CObjB Constructor..." << endl; }
  ~CObjB() { cout << "CObjB Destructor..." << endl; }
  shared_ptr<CObjA> m_pa; // 在B中引用A
};
int main() {
  shared_ptr<CObjA> tmpPa = make_shared<CObjA>();
  shared_ptr<CObjB> tmpPb = make_shared<CObjB>();
  tmpPa->m_pb = tmpPb;
  tmpPb->m_pa = tmpPa;
  std::cout << "CObjA referencr num:" << tmpPa.use_count() << endl;
  std::cout << "CObjB referencr num:" << tmpPb.use_count() << endl;
//  tmpPa->m_pb.reset();
//  tmpPb->m_pa.reset();
//  std::cout << "CObjA referencr num:" << tmpPa.use_count() << endl;
//  std::cout << "CObjB referencr num:" << tmpPb.use_count() << endl;
}

我們可以看到在出main函數(shù)作用域之前兩個指針指向的內(nèi)存并沒有釋放(指針指向的對象沒有調(diào)用析構(gòu)函數(shù)),我門把當(dāng)前的引用數(shù)打印出來為2這個沒有問題,為什么在函數(shù)結(jié)束時沒有調(diào)用對象的析構(gòu)函數(shù)呢?這就好像多線程之間的死鎖一樣,對象a想要析構(gòu)但是發(fā)現(xiàn)對象b引用了自己所以就等待對象b析構(gòu)不再引用自己,而b想要析構(gòu)卻發(fā)現(xiàn)對象a引用了自又等待a析構(gòu)如此就導(dǎo)致兩個指針指向的對象沒有析構(gòu)釋放內(nèi)存,這就是循環(huán)引用導(dǎo)致的內(nèi)存問題。

如何證明這個結(jié)論呢,我們手動釋放掉兩個對象對對方的引用,就可以解除循環(huán)引用關(guān)系,正確析構(gòu)對象了(把注釋部分代碼打開)。運行結(jié)果:

我門可以看到,調(diào)用reset函數(shù)釋放引用關(guān)系后,指針的引用計數(shù)變?yōu)橐?,等到函?shù)運行結(jié)束,兩個shared指針生命周期結(jié)束調(diào)用析構(gòu)函數(shù),對象的引用計數(shù)減為0,對象內(nèi)存釋放。

但是如果每次都要手動解除引用來解決循環(huán)引用,那么智能指針似乎變成了傻子指針了,這時候還有一個東西能解決,那就是weak_ptr,它不會改變所共享的shared_ptr的引用計數(shù),即使我門可以通過該指針訪問它所指向的對象。 

//
// main.cpp
// test
//
// Created by 杜國超 on 17/9/9.
// Copyright © 2017年 杜國超. All rights reserved.
//
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class CObjB;
class CObjA
{
public:
  CObjA() { cout << "CObjA Constructor..." << endl; }
  ~CObjA() { cout << "CObjA Destructor..." << endl;}
  void Say() {cout << "CObjA Say..." << endl; }
  shared_ptr<CObjB> GetPb() {
    return m_pb.lock();
  }
public:
  weak_ptr<CObjB> m_pb; // 在A中引用B
};
class CObjB
{
public:
  CObjB() { cout << "CObjB Constructor..." << endl; }
  ~CObjB() { cout << "CObjB Destructor..." << endl; }
  void Say() {cout << "CObjB Say..." << endl; }
  shared_ptr<CObjA> GetPa() {
    return m_pa.lock();
  }
public:
  weak_ptr<CObjA> m_pa; // 在B中引用A
};
int main() {
  shared_ptr<CObjA> tmpPa = make_shared<CObjA>();
  shared_ptr<CObjB> tmpPb = make_shared<CObjB>();
  tmpPa->m_pb = tmpPb;
  tmpPb->m_pa = tmpPa;
  std::cout << "CObjA referencr num:" << tmpPa.use_count() << endl;
  std::cout << "CObjB referencr num:" << tmpPb.use_count() << endl;
  if (tmpPa->GetPb()!= NULL){
    tmpPa->GetPb()->Say();
  }
  if (tmpPb->GetPa()!= NULL){
    tmpPb->GetPa()->Say();
  }
}

這樣就得到我門想要的結(jié)果了。最后說一句雖然智能指針帶來了很多方便,但是也要小心使用它仍然有很多坑等著我門,以后再作詳述。

總結(jié)

以上所述是小編給大家介紹的C++中的循環(huán)引用,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 賭你會懵的C語言指針進階數(shù)組場景解析

    賭你會懵的C語言指針進階數(shù)組場景解析

    這篇文章主要為大家介紹了關(guān)于C語言指針進階的示例解析,來細化指針這一部分內(nèi)容,現(xiàn)在著重把一些指針的運用情景搬出來康康,如果對指針盤的不是非常熟練,或者指針還出于入門階段的鐵子請繞道
    2022-02-02
  • 通過c語言調(diào)用系統(tǒng)curl動態(tài)庫的示例詳解

    通過c語言調(diào)用系統(tǒng)curl動態(tài)庫的示例詳解

    這篇文章中我們將通過一個簡單的示例來講解如何在Ubuntu系統(tǒng)中通過C語言調(diào)用動態(tài)庫(共享庫)的方法,我們將使用libcurl庫,這是一個基于客戶端的URL傳輸庫,廣泛用于各種程序和應(yīng)用中以訪問網(wǎng)頁和服務(wù)器數(shù)據(jù),需要的朋友可以參考下
    2024-03-03
  • 深入探討Linux靜態(tài)庫與動態(tài)庫的詳解(一看就懂)

    深入探討Linux靜態(tài)庫與動態(tài)庫的詳解(一看就懂)

    本篇文章是對Linux靜態(tài)庫與動態(tài)庫進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 基于MFC實現(xiàn)貪吃蛇小游戲

    基于MFC實現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細介紹了基于MFC實現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 基于OpenCV實現(xiàn)車道線檢測(自動駕駛 機器視覺)

    基于OpenCV實現(xiàn)車道線檢測(自動駕駛 機器視覺)

    無人駕駛技術(shù)是機器學(xué)習(xí)為主的一門前沿領(lǐng)域,在無人駕駛領(lǐng)域中機器學(xué)習(xí)的各種算法隨處可見,本文將為大家介紹無人駕駛技術(shù)中的車道線檢測,感興趣的小伙伴可以了解一下
    2021-11-11
  • 解析C++哈夫曼樹編碼和譯碼的實現(xiàn)

    解析C++哈夫曼樹編碼和譯碼的實現(xiàn)

    本篇文章主要介紹了C++哈夫曼樹編碼和譯碼的實現(xiàn),詳細的講訴了哈夫曼樹編碼的原理,有需要的同學(xué)可以了解一下。
    2016-11-11
  • 詳解C++中的inline用法

    詳解C++中的inline用法

    在c/c++中,為了解決一些頻繁調(diào)用的小函數(shù)大量消耗棧空間(棧內(nèi)存)的問題,特別的引入了inline修飾符,表示為內(nèi)聯(lián)函數(shù)。 ??臻g就是指放置程序的局部數(shù)據(jù)(也就是函數(shù)內(nèi)數(shù)據(jù))的內(nèi)存空間
    2017-09-09
  • C++ 轉(zhuǎn)換函數(shù)用法案例詳解

    C++ 轉(zhuǎn)換函數(shù)用法案例詳解

    這篇文章主要介紹了C++ 轉(zhuǎn)換函數(shù)用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • C語言學(xué)生學(xué)籍管理系統(tǒng)課程設(shè)計

    C語言學(xué)生學(xué)籍管理系統(tǒng)課程設(shè)計

    這篇文章主要介紹了C語言學(xué)生學(xué)籍管理系統(tǒng)課程設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 利用C語言編寫“剪刀石頭布”小游戲

    利用C語言編寫“剪刀石頭布”小游戲

    這篇文章主要給大家介紹了關(guān)于如何利用C語言編寫“剪刀石頭布”小游戲的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評論

贡嘎县| 个旧市| 杂多县| 闽清县| 衡水市| 凌海市| 大名县| 定边县| 芦溪县| 廉江市| 南皮县| 长沙县| 衡水市| 水城县| 文安县| 和顺县| 天门市| 安龙县| 印江| 清镇市| 建水县| 沅江市| 任丘市| 馆陶县| 修武县| 芷江| 辉南县| 广东省| 报价| 平果县| 平定县| 平舆县| 十堰市| 新津县| 林甸县| 通渭县| 祁门县| 武义县| 泌阳县| 黄浦区| 邵阳县|