练习13.27:引用计数版本的HasPtr类
#include <iostream>
#include <string>
using namespace std;
#include <vector>
class HasPtr {
public:
//构造函数分配新的string和计数器,将计数器置为1
HasPtr(const std::string& s = std::string()): ps(new std::string(s)),i(0),use(new std::size_t(1)) { }
//拷贝构造函数拷贝所有三个数据成员,并递增计数器
HasPtr(const HasPtr& p) :ps(p.ps), i(p.i), use(p.use) { ++* use; }
HasPtr& operator=(const HasPtr&);
~HasPtr();
private:
std::string* ps;
int i;
//记录有多少个对象共享*ps的成员
std::size_t* use;
};
HasPtr::~HasPtr()
{
if (-- * use == 0)
{
delete ps;
delete use;
}
}
HasPtr& HasPtr::operator=(const HasPtr& rhs)
{
++* rhs.use;
if (-- * use == 0)
{
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}
练习13.28:
a)TreeNode类
#include <iostream>
#include <string>
using namespace std;
#include <vector>
class TreeNode {
public:
//默认构造函数,TreeNode类型的指针赋值为空
TreeNode():left(nullptr),right(nullptr) { }
//拷贝构造函数
TreeNode(const TreeNode& t):value(t.value),count(t.count),
left(new TreeNode(*t.left)),right(new TreeNode(*t.right)) { }
//传参拷贝
TreeNode(std::string v,int c, const TreeNode& lf, const TreeNode& rf):value(v),count(c),
left(new TreeNode(lf)),right(new TreeNode(rf)) { }
//拷贝赋值运算符
TreeNode& operator=(const TreeNode& t);
//析构
~TreeNode();
private:
std::string value;
int count;
//拷贝时要拷贝指针指向的对象,而不是拷贝指针
TreeNode* left;
TreeNode* right;
};
//拷贝赋值运算符
TreeNode& TreeNode::operator=(const TreeNode& t)
{
//释放左边对象内存前先拷贝右边对象内存,防止自赋值造成对象被释放
value = t.value;
count = t.count;
if (t.left == nullptr)
{
delete left;
left = nullptr;
}
else
{
delete left;
left = new TreeNode(*t.left);
}
if (t.right == nullptr)
{
delete right;
right = nullptr;
}
else
{
delete right;
right = new TreeNode(*t.right);
}
return *this;
}
//析构
TreeNode::~TreeNode()
{
//delete空指针是可以的
delete left;
delete right;
}
b)TreeNode类+BinStrTree类
#include <iostream>
#include <string>
using namespace std;
#include <vector>
class TreeNode {
public:
//默认构造函数,TreeNode类型的指针赋值为空
TreeNode():left(nullptr),right(nullptr) { }
//拷贝构造函数
TreeNode(const TreeNode& t):value(t.value),count(t.count),
left(new TreeNode(*t.left)),right(new TreeNode(*t.right)) { }
//传参拷贝
TreeNode(std::string v,int c, const TreeNode& lf, const TreeNode& rf):value(v),count(c),
left(new TreeNode(lf)),right(new TreeNode(rf)) { }
//拷贝赋值运算符
TreeNode& operator=(const TreeNode& t);
//析构
~TreeNode();
private:
std::string value;
int count;
//拷贝时要拷贝指针指向的对象,而不是拷贝指针
TreeNode* left;
TreeNode* right;
};
//拷贝赋值运算符
TreeNode& TreeNode::operator=(const TreeNode& t)
{
//释放左边对象内存前先拷贝右边对象内存,防止自赋值造成对象被释放
value = t.value;
count = t.count;
if (t.left == nullptr)
{
delete left;
left = nullptr;
}
else
{
delete left;
left = new TreeNode(*t.left);
}
if (t.right == nullptr)
{
delete right;
right = nullptr;
}
else
{
delete right;
right = new TreeNode(*t.right);
}
return *this;
}
//析构
TreeNode::~TreeNode()
{
//delete空指针是可以的
delete left;
delete right;
}
class BinStrTree {
public:
//默认构造函数
BinStrTree():root(nullptr){ }
//拷贝构造函数
BinStrTree(const BinStrTree& bs):root(new TreeNode(*bs.root)) { }
//传参构造
BinStrTree(const TreeNode* r):root(new TreeNode(*r)) { }
//拷贝赋值运算符
BinStrTree& operator=(const BinStrTree& bs);
//析构函数
~BinStrTree();
private:
TreeNode* root;
};
//拷贝赋值运算符
BinStrTree& BinStrTree::operator=(const BinStrTree& bs)
{
auto newPtr = new TreeNode(*bs.root);
delete root;
root = newPtr;
return *this;
}
//析构函数
BinStrTree:: ~BinStrTree()
{
delete root;
}