简介

引用计数就是对一个对象记录其被引用的次数,其的引用计数可加可减,那什么时候加什么时候减呢?所以引用计数的重点在于在哪里加,在哪里减;

加:

减:

实现

//
// Ref.hpp
// Ref
//
// Created by George on 16/11/6.
// Copyright © 2016年 George. All rights reserved.
// #ifndef Ref_hpp
#define Ref_hpp #include <iostream>
#include <string> template <typename T>
class RefPtr; template <typename T>
class Ref {
private:
Ref(T *ptr);
~Ref(); friend class RefPtr<T>; //定义指针管理类为友元,因为管理类需要直接操作指针类 /**
* 增加引用计数
*/
void ref(); /**
* 减少引用计数
*
* @param count <#count description#>
*/
void unref(); /**
* 返回引用计数的个数
*
* @return <#return value description#>
*/
int getCount(); private:
int count; //引用计数
T *p; //基础对象指针
}; template <typename T>
Ref<T>::Ref(T *ptr) : p(ptr), count(1) { } template <typename T>
Ref<T>::~Ref() {
// count--;
// if (count <= 0) {
// count = 0;
// delete p;
// }
delete p;
} template <typename T>
void Ref<T>::ref() {
count++;
} template <typename T>
void Ref<T>::unref() {
count--;
if (count < 0) {
count = 0;
}
} template <typename T>
int Ref<T>::getCount() {
return count;
} template <typename T>
class RefPtr {
public:
RefPtr(T *ptr);
RefPtr(const RefPtr<T>&);
~RefPtr(); RefPtr& operator=(const RefPtr<T>&);
T & operator*();
T * operator->(); inline std::string getTag() { return _tag; };
void setTag(const std::string value) { _tag = value; }; inline int getRefCount() { return ref->getCount(); } private:
Ref<T> *ref;
std::string _tag;
}; /**
* 构造函数
*/
template <typename T>
RefPtr<T>::RefPtr(T *ptr) : ref(new Ref<T>(ptr)), _tag("") { } /**
* 构造函数,不需要对参数进行计数操作
*/
template <typename T>
RefPtr<T>::RefPtr(const RefPtr<T> & nref) {
ref = nref.ref;
ref->ref();
_tag = "";
} /**
* 销毁函数
*/
template <typename T>
RefPtr<T>::~RefPtr() {
ref->unref();
if (ref->getCount() <= 0) {
delete ref;
}
std::cout << this->getTag() << " leave " << ref->getCount() << "次" << std::endl;
} /**
* 重载操作符=
* 左值引用计数减一,右值引用计数加一
*
* @param rhs <#rhs description#>
*
* @return <#return value description#>
*/
template <typename T>
RefPtr<T> & RefPtr<T>::operator=(const RefPtr<T>& rhs) {
rhs->ref->ref();
ref->unref(); if (ref->getCount() <= 0) {
delete ref;
} ref = rhs->ref; return *this;
} /**
* 重载操作符*
*
* @return <#return value description#>
*/
template <typename T>
T & RefPtr<T>::operator*() {
return *(ref->p);
} /**
* 重载->操作符
*
* @return <#return value description#>
*/
template <typename T>
T * RefPtr<T>::operator->() {
return ref->p;
} #endif /* Ref_hpp */

其中Ref是引用,而RefPtr是对Ref进行操作的封装,在什么时候加减;

测试

//
// main.cpp
// Ref
//
// Created by George on 16/11/6.
// Copyright © 2016年 George. All rights reserved.
// #include <iostream>
#include "Ref.hpp" int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n"; int *num = new int(2);
{
RefPtr<int> ptr(num);
{
ptr.setTag("Ptr1");
RefPtr<int> ptr2(ptr);
{
ptr2.setTag("Ptr2"); RefPtr<int> ptr3 = ptr2;
ptr3.setTag("Ptr3");
{
int *nnum = new int(4);
RefPtr<int> ptr4(nnum);
ptr4.setTag("Ptr4"); std::cout << "ptr:" << *ptr << std::endl; *ptr = 20; std::cout << "ptr3:" << *ptr3 << std::endl; std::cout << "ptr1 have " << ptr.getRefCount() << "次" << std::endl;
std::cout << "ptr2 have " << ptr2.getRefCount() << "次" << std::endl;
std::cout << "ptr3 have " << ptr3.getRefCount() << "次" << std::endl;
std::cout << "ptr4 have " << ptr4.getRefCount() << "次" << std::endl;
}
}
}
} return 0;
}

结果如下

C++引用计数的更多相关文章

  1. Objective-C内存管理之引用计数

    初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存 ...

  2. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  3. C++ 引用计数技术及智能指针的简单实现

    一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...

  4. 【Python】引用计数

    一.概述 要保持追踪内存中的对象,Python使用了引用计数这一简单的技术. 二.引用计数的增减 2.1 增加引用计数 当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1. 对象的引用 ...

  5. iOS开发--引用计数与ARC

    以下是关于内存管理的学习笔记:引用计数与ARC. iOS5以前自动引用计数(ARC)是在MacOS X 10.7与iOS 5中引入一项新技术,用于代替之前的手工引用计数MRC(Manual Refer ...

  6. Objective-C内存管理之-引用计数

    本文会继续深入学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记 内存管理 1 内存管理的基本概念 1.1 Objective-C中的 ...

  7. 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数

    1.linux find export find /Applications/Xcode.app/ -name symbolicatecrash -type f export DEVELOPER_DI ...

  8. swif-自动引用计数

    import UIKit /* class Person { let name: String //强引用 init(name: String) { self.name = name print(&q ...

  9. OC中的自动引用计数

    目录: 1,自动引用计数的定义 2,强引用和弱引用 3,类比手动引用 4,循环引用 5,CoreFoundation 内容: 自动引用计数的定义: (Automatic Reference Count ...

  10. ATL是如何实现线程安全的引用计数和多线程控制的

    ATL是如何实现线程安全的引用计数和多线程控制的 正如标题所示,这是我经常被问到的一个问题,而每次我都从头开始给人说一次,其实说来过程理解起来的确有点复杂. 我们的每一个ATL Server Obje ...

随机推荐

  1. 汽车OBD2诊断程序开发 (原文转载,思路很清晰!)

    1.因TL718已经为你建立了物理层.数据链层和部分应用层的协议,所以只要OBD2标准应用层协议文本,ISO15031-5 或 SAE J1979(这两个协议是相同的内容).    2.TL718诊断 ...

  2. AT-Activity

    关于Activity的粗略翻译 原地址:Activity  类概述: Activity是独立的.突出的可被用户操作的东西.几乎所有的Activity都是与用户进行交互的,所以这些Activity会很小 ...

  3. ASP FSO操作文件(复制文件、重命名文件、删除文件、替换字符串)

    ASP FSO操作文件(复制文件.重命名文件.删除文件.替换字符串)FSO的意思是FileSystemObject,即文件系统对象.FSO对象模型包含在Scripting 类型库 (Scrrun.Dl ...

  4. openlayers wfs获取要素

    var wfsProtocol = new OpenLayers.Protocol.WFS.v1_1_0({ url: mapServerUrl + "/wfs", feature ...

  5. 【JAVA】浅谈java枚举类

    一.什么情况下使用枚举类? 有的时候一个类的对象是有限且固定的,这种情况下我们使用枚举类就比较方便? 二.为什么不用静态常量来替代枚举类呢? public static final int SEASO ...

  6. [openMP] OpenMP在visual studio和mac上的配置

    今天弄了半天才弄好mac上的openmp,一方面智商下限,另一方面竟然发现网上也没有什么详细过程,特意把我的配置过程贴上来 多核编程可以认为是对多线程编程做了一定程度的抽象,提供一些简单的API,使得 ...

  7. [Effective Objective-C 读书笔记] 第1章 几条基本写法 (2~5条)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3575599.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  8. 用分治法实现大数乘法,加法,减法(java实现)

    大数乘法即多项式乘法问题,求A(x)与B(x)的乘积C(x),朴素解法的复杂度O(n^2),基本思想是把多项式A(x)与B(x)写成 A(x)=a*x^m+b B(x)=c*x^m+d 其中a,b,c ...

  9. 关闭一个winform窗体刷新另外一个

    例如Form1是你的主窗体,然后Form2是你的要关闭那个窗体,在Form1中SHOW FORM2的窗体那里加上一句f2.FormClosed += new FormClosedEventHandle ...

  10. 图片裁切插件jCrop的使用心得(一)

    之前,项目经理为了提升用户体验让我在之前图片上传功能的基础上实现图片的裁切功能,作为一个前端小白来说听了这个需求心里一紧,毕竟没有做过,于是跟项目经理商量要先做下调研.在一上午的调研中发现了jCrop ...