#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;
}
重载赋值运算符--引用计数
最新推荐文章于 2022-02-13 09:19:41 发布