C++引用计数

//reference count, copy-on-write
#include <stdio.h>
#include <iostream>
#include <../require.h>
#include <string>

using namespace std;

class Dog
{
    string nm;
    int refcount;
    Dog(const string& name)
        : nm(name), refcount(1)
    {
        cout << "creating Dog:" << *this << endl;
    }
    //prevent assignment:
    Dog& operator=(const Dog& rv);
public:
    //Dogs can only be  created on the heap
    static Dog* make(const string& name)
    {
        return new Dog(name);
    }
    Dog(const Dog& d)
        : nm(d.nm + "copy"), refcount(1)
    {
        cout << "Dog copy-constructor:" << *this << endl;
    }
    ~Dog()
    {
        cout << "Attached Dog:" << *this << endl;
    }
    void attach()
    {
        ++refcount;
        cout << "Attach Dog:" << *this << endl;
    }
    void  detach()
    {
        require(refcount != 0);
        cout << "Detaching Dog:" << *this << endl;
        //destroy object if no one is using it :
        if (--refcount == 0) delete this;
    }
    //conditionally copy this dog
    //call before modifying the dog,assign
    //resulting pointer to your Dog*
    Dog* unalias()
    {
        cout << "unaliasing dog:" << *this << endl;
        //not duplicate if not aliased;
        if (refcount == 1)
            return this;
        --refcount;
        //use copy-constructor to duplicate:
        return new Dog(*this);
    }
    void rename(const string& newName)
    {
        nm = newName;
        cout << "Dog renamed to:" << *this << endl;
    }
    friend ostream& operator<<(ostream& os, const Dog& d)
    {
        return os << "[" << d.nm << "],rc=" << d.refcount << endl;
    }
};

class DogHouse
{
    Dog* p;
    string houseName;
public:
    DogHouse(Dog* dog, const string& house)
        : p(dog), houseName(house)
    {
        cout << "created DogHouse:" << *this << endl;
    }
    DogHouse(const DogHouse& dh)
        : p(dh.p),
        houseName("copy-constructed" + dh.houseName)
    {
        p->attach();
        cout << "DogHouse copy-constructor:" << *this << endl;
    }
    DogHouse& operator=(const DogHouse& dh)
    {
        //check for self-assignment:
        if (&dh != this)
        {
            houseName = dh.houseName + "assigned";
            //clean up what you‘re using first:
            p->detach();
            p = dh.p;//like copy-constructor
            p->attach();
        }
        cout << "DogHouse operator=:" << *this << endl;
        return *this;
    }
    //decrement refcount, conditionally destroy
    ~DogHouse()
    {
        cout << "DogHouse destructor:" << *this << endl;
        p->detach();
    }
    void renameHouse(const string& newName)
    {
        houseName = newName;
    }
    void unalias()
    {
        p = p->unalias();
    }
    //copy-on-write.anytime you modify the
    //contents of the pointer you must first unalias it:
    void renameDog(const string& newName)
    {
        unalias();
        p->rename(newName);
    }
    //...or when you allow someone else access:
    Dog* getDog()
    {
        unalias();
        return p;
    }
    friend ostream& operator<<(ostream& os, const DogHouse& dh)
    {
        return os << "[" << dh.houseName << "] contains " << *dh.p;
    }
};

int main()
{
    DogHouse fidos(Dog::make("Fido"), "FidoHouse"),
    spots(Dog::make("Spot"), "SpotHouse");
    cout << "entering copy-construction" << endl;
    DogHouse bobs(fidos);
    cout << "After copy-constructing bobs" << endl;
    cout << "fidos:" << fidos << endl;
    cout << "spots:" << spots << endl;
    cout << "bobs:" << bobs << endl;
    cout << "Entering spots = fidos" << endl;
    spots = fidos;
    cout << "After spots=fidos" << endl;
    cout << "spots:" << spots << endl;
    cout << "entering self-assignment" << endl;
    bobs = bobs;
    cout << "After self-assignment" << endl;
    cout << "bobs:" << bobs << endl;
    //comment out the following lines
    cout << "entering rename(\"Bob\")" << endl;
    bobs.getDog()->rename("Bob");
    cout << "After rename(\"Bob\")" << endl;
}
时间: 2025-01-10 16:14:49

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

实现类似shared_ptr的引用计数

13.27 定义使用引用计数版本的HasPtr #include<iostream> #include<string> #include<new> using namespace std; class HasPtr { public: HasPtr(const string &s=string()):ps(new string(s)),i(0),use(new size_t(1)) {cout<<"constructer"<

深拷贝&amp;浅拷贝&amp;引用计数&amp;写时拷贝

(1).浅拷贝: class String { public: String(const char* str="") :_str(new char[strlen(str)+1]) { strcpy(_str,str); } ~String() { if(NULL!=_str) { delete[] _str; _str=NULL; } } private: char* _str; }; int main() { String s1("hello"); String

手工引用计数中规则

使用设值方法为属性赋值时 assign.retain.copy三个特性的实现 self.property = newValue; assign的特性会是这样: property = newValue; retain特性会是这样 if (property!=0) { [property release]; property = [newValue retain]; } copy的特性会是这样 if (property!=0) { [property release]; property = [ne

Objective-C中的引用计数

导言 Objective-C语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数器.如果想使某个对象继续存活,那就递增其引用计数:用完了之后,就递减其计数.计数为0,就表示没人关注此对象了,于是,就可以把它销毁. 从Mac OS X 10.8开始,“垃圾收集器”(garbage collector)已经正式废弃了,以Objective-C代码编写Mac OS X程序时不应再使用它,而iOS则从未支持过垃圾收集.因此,掌握引用计数机制对于学好Objective-C来说十分重要.

引用计数

在引用计数中,每一个对象负责维护对象所有引用的计数值.当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减.当引用计数到零时,该对象就将释放占有的资源.中文名引用计数原 因程序调试原 理每一个对象负责维护对象所有引用的计数值类 型最直观的垃圾收集策略目录1简介2引用计数的使用? 原因? 规则? 接口? 调试? 优化? 规则1简介编辑 最直观的垃圾收集策略是引用计数.引用计数很简单,但是需要编译器的重要配合,并且增加了赋值函数 (mutator) 的开销(这个术语是针对用户

基于引用计数的智能指针

编程语言中实现自动垃圾回收机制方式有好几种,常见的有标记清除,引用计数,分代回收等. C++需要手动管理垃圾,可以自己实现一个智能指针.最简单的是引用计数的思路 template <class T> class SmartPointer { T* obj; unsigned int* count; SmartPointer(T* ptr) { obj = ptr; count = new int; *count = 1; } SmartPointer(SmartPointer &p)

ARC自动引用计数

启动自动引用计数选项. 选择项目的属性文件 --> 搜索 automatic Reference --> Objective-C Automatic Reference Counting --> Yes ARC 和手动管理内存的区别. ARC 并不是GC在运行中判断引用计数是否为0,从而清除内存.而是在代码编译之前通过静态分析工具Analyze自动生成内存管理代码. 开启ARC后,不能再使用retain等系列手动内存管的方法,可以重写dealloc方法但不能再方法中[super deal

netty的引用计数

netty的引用计数文档看http://netty.io/wiki/reference-counted-objects.html 为什么会引用引用计数呢,Java中不是有gc线程帮我们回收对象吗?我个人理解如下 1:netty为了实现zero copy使用了Direct Buffer,该buffer从Native Memory分配出来,分配和回收效率要远低于在Java Heap上的对象,所以一般full gc来控制的,直接内存会自己检测情况而调用system.gc(),通过使用引用计数可以自己来

智能指针的实现--使用引用计数实现以及原理

一.智能指针 在C++语言编程时,当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝:另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享. 智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count).智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针. 每次创建类的新对象时,初始化指针并将引用计数置为1:当对象作为另一对象的副本而创建时,拷贝

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

初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存管理这一部分说的非常简单,只有三条准则: 当你使用new.alloc或copy方法创建一个对象时,该对象的保留指针为1,当不再使用该对象的时候,你应该想该对象发送一条release或autorelease消息,这样,该对象在其寿命结束时将被销毁. 当你通过其他方法获得一个对象时,假设该对象的保留计数