重载赋值运算符--引用计数

#include <iostream>
#include <string>

using namespace std;

class Dog
{
private:
	string nm;
	int refcount; // 引用计数,
	Dog(const string& name) : nm(name), refcount(1)
	{
		cout << "Creating Dog: " << *this << endl;
	}
public:
	static Dog* make(const string& name)
	{
		return new Dog(name); // 这个表示只允许在堆上创建对象,不允许在栈上创建对象,
	}
	~Dog()
	{
		cout << "Deleting Dog: " << *this << endl;
	}
	Dog(const Dog& d) : nm(d.nm + " copy "), refcount(1)
	{
		cout << "Dog copy-constructor: " << *this << endl;
	}
	void attach()
	{
		++refcount;
		cout << "Attached Dog: " << *this << endl;
	}
	void detach()
	{
		cout << "Detching Dog: " << *this << endl;
		if (--refcount == 0)
			delete this;
	}
	void rename(const string& newName)
	{
		nm = newName;
		cout << "Dog renamed to: " << *this << endl;
	}
	Dog* unalias()  // 这个是取消别名,
	{
		cout << "Unaliasing Dog: " << *this << endl;
		if (refcount == 1) return this;
		--refcount; // 这是引用计数减一,
		return new Dog(*this);  // 创建新的
	}

	friend ostream& operator<<(ostream& os, const Dog& d)
	{
		return os << "[" << d.nm << "], rc = " << d.refcount;
	}
};

class DogHouse
{
private:
	Dog* p;
	string houseName;
public:
	DogHouse(Dog* dog, const string& house) :p(dog), houseName(house)
	{

	}
	DogHouse(const DogHouse& dh) :p(dh.p), houseName(dh.houseName + " copy-constructed")
	{
		p->attach();
		cout << "DogHouse copy-constructor: " << *this << endl;
	} 
	DogHouse& operator=(const DogHouse& dh)
	{
		if (&dh != this)
		{
			p->detach();  // 这个是减一,
			p = dh.p;
			p->attach();
		}
		cout << "DogHouse operator= : " << *this << endl;
		return *this;
	}
	~DogHouse()
	{
		cout << "DogHouse destructor: " << *this << endl;
		p->detach();
	}
	
	void rename(const string& newName)
	{
		houseName = newName;
	}
	// copy - on -write
	void unalias()
	{
		p = p->unalias(); // copy-on-write
	}
	Dog* getDog() 
	{
		unalias(); // 这个去除别名,判断要不要进行复制,
		return p;
	}
	void renameDog(const string& newName)
	{
		unalias();
		p->rename(newName);
	}

	friend ostream& operator<<(ostream& os, const DogHouse& dh)
	{
		return os << "[" << dh.houseName << "] constains " << *dh.p;
	}
};

int main()
{
	DogHouse a(Dog::make("A"), "AHouse");
	cout << a << endl << endl;

	DogHouse b(a);
	DogHouse c = a;

	cout << "..... " << endl;
	c.renameDog("CDog");
	cout << " a: " << a << endl << endl;
	cout << " c: " << c << endl << endl;


	return 0;
}

你可能感兴趣的:(重载赋值运算符--引用计数)