C++引用计数

//reference count, copy-on-write
//注意:delete this;析构函数调用以及operator<<()运算符的使用;
#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; }
怕什么真理无穷,进一寸有一寸的欢喜。---胡适
原文地址:https://www.cnblogs.com/hujianglang/p/7255755.html