⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 refcounttrace.cpp

📁 Think in C++ 第二版源码
💻 CPP
字号:
//: C12:RefcountTrace.cpp

// From Thinking in C++, 2nd Edition

// Available at http://www.BruceEckel.com

// (c) Bruce Eckel 1999

// Copyright notice in Copyright.txt

// Refcount.cpp w/ trace info

#include "../require.h"

#include <cstring>

#include <fstream>

using namespace std;



ofstream out("rctrace.out");



class Counted {

  class MemBlock {

    static const int size = 100;

    char c[size];

    int refcount;

    static int blockcount;

    int blocknum;

  public:

    MemBlock() {

      memset(c, 1, size);

      refcount = 1;

      blocknum = blockcount++;

    }

    MemBlock(const MemBlock& rv) {

      memcpy(c, rv.c, size);

      refcount = 1;

      blocknum = blockcount++;

      print("copied block");

      out << endl;

      rv.print("from block");

    }

    ~MemBlock() {

      out << "\tdestroying block "

          << blocknum << endl;

    }

    void print(const char* msg = "") const {

      if(*msg) out << msg << ", ";

      out << "blocknum:" << blocknum;

      out << ", refcount:" << refcount;

    }

    void attach() { ++refcount; }

    void detach() {

      require(refcount != 0);

      // Destroy object if no one is using it:

      if(--refcount == 0) delete this;

    }

    int count() const { return refcount; }

    void set(char x) { memset(c, x, size); }

    // Conditionally copy this MemBlock.

    // Call before modifying the block; assign

    // resulting pointer to your block;

    MemBlock* unalias() {

      // Don't duplicate if not aliased:

      if(refcount == 1) return this;

      --refcount;

      // Use copy-constructor to duplicate:

      return new MemBlock(*this);

    }

  }* block;

  static const int sz = 30;

  char ident[sz];

public:

  Counted(const char* id = "tmp") {

    block = new MemBlock; // Sneak preview

    strncpy(ident, id, sz);

  }

  Counted(const Counted& rv) {

    block = rv.block; // Pointer assignment

    block->attach();

    strncpy(ident, rv.ident, sz);

    strncat(ident, " copy", sz - strlen(ident));

  }

  void unalias() { block = block->unalias(); }

  void addname(const char* nm) {

    strncat(ident, nm, sz - strlen(ident));

  }

  Counted& operator=(const Counted& rv) {

    print("inside operator=\n\t");

    if(&rv == this) {

      out << "self-assignment" << endl;

      return *this;

    }

    // Clean up what you're using first:

    block->detach();

    block = rv.block; // Like copy-constructor

    block->attach();

    return *this;

  }

  // Decrement refcount, conditionally destroy

  ~Counted() {

    out << "preparing to destroy: " << ident

        << "\n\tdecrementing refcount ";

    block->print();

    out << endl;

    block->detach();

  }

  // Copy-on-write:

  void write(char value) {

    unalias();

    block->set(value);

  }

  void print(const char* msg = "") {

    if(*msg) out << msg << " ";

    out << "object " << ident << ": ";

    block->print();

    out << endl;

  }

};



int Counted::MemBlock::blockcount = 0;



int main() {

  Counted A("A"), B("B");

  Counted C(A);

  C.addname(" (C) ");

  A.print();

  B.print();

  C.print();

  B = A;

  A.print("after assignment\n\t");

  B.print();

  out << "Assigning C = C" << endl;

  C = C;

  C.print("calling C.write('x')\n\t");

  C.write('x');

  out << "\n exiting main()" << endl;

} ///:~

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -