c++记录知识----------------实现一个像vector的动态内存管理类

class StrVec
{
private:
	static allocator<string> alloc;		//静态变量,用来分配元素
	string *elements;					//首元素
	string *first_free;					//指向第一个空闲的元素	
	string *cap;						//指向数组尾后位置的元素

	//检查内存是否够用
	void chk_n_alloc()
	{
		if (size() == capacity()) reallocate();
	}
	//创造一个从b到e的内存,并赋值,返回首元素和末元素之后的位置
	pair<string*, string*> alloc_n_copy(const string*, const string*);		
	void free();			//销毁元素并释放内存
	void reallocate();		//获得更多内存,并拷贝已有元素


public:
	StrVec() :elements(nullptr), first_free(nullptr), cap(nullptr) {};
	StrVec(const StrVec&);		//拷贝构造函数
	StrVec &operator=(const StrVec&);
	~StrVec();

	void push_back(const string&);
	size_t size() { return first_free - elements; };
	size_t capacity() { return cap - elements; };
	string *begin() const { return elements; };
	string *end() const { return first_free; };
};



void StrVec::push_back(const string& s)
{
	chk_n_alloc();

	alloc.construct(first_free++,s);
}

pair<string*, string*> StrVec::alloc_n_copy(const string *b, const string *e)
{
	auto data = alloc.allocate(e - b);
	return { data,uninitialized_copy(b,e,data) };
}

void StrVec::free()
{
	if (elements)
	{
		for (auto p = first_free; p != elements;)
			alloc.destroy(--p);
		alloc.deallocate(elements, cap - elements);
	}
}

StrVec::StrVec(const StrVec &s)
{
	auto newdata = alloc_n_copy(s.begin(), s.end());
	elements = newdata.first;
	first_free = cap = newdata.second;
}

StrVec::~StrVec()
{
	free();
}

StrVec &StrVec::operator=(const StrVec&rhs)
{
	auto data= alloc_n_copy(rhs.begin(), rhs.end());
	free();
	elements = data.first;
	first_free = cap = data.second;
	return *this;
}

void StrVec::reallocate()
{
	auto newcapacity = size() ? 2 * size() : 1;
	auto newdata = alloc.allocate(newcapacity);
	auto dest = newdata;		//首元素
	auto elem = elements;
	for (size_t i = 0; i != size(); ++i)
		alloc.construct(dest++, std::move(*elements++));
	free();
	elements = newdata;
	first_free = dest;
	cap = elements + newcapacity;

}

下面是拷贝控制的应用 

using namespace std;

class Folder
{
private:
	set<Message*> msg;

public:
	Folder() {};

	Folder &operator=(const Folder &f)
	{
		msg = f.msg;
	}

	void addMsg(Message *m)
	{
		msg.insert(m);
	}

	void remMsg(Message *m)
	{
		if(msg.find(m)!=msg.end())	msg.erase(m);
		
	}

};





class Message
{
	friend class Folder;
	friend void swap(Message &lhs, Message&rhs);
private:
	string contents;	//实际消息文本
	set<Folder*> folders;		//包含文本Message的folder


	//拷贝构造函数,拷贝赋值运算符和析构函数所使用的工具函数
	//讲文本Message添加到Folder中
	void add_to_Folders(const Message&);

	void remove_from_Folders();

public:
	//folders被隐式初始化为空集合
	explicit Message(const string &str = "") :contents(str) {};

	//拷贝控制成员,用来管理指向本Message的指针
	Message(const Message&);
	Message &operator=(const Message&);
	~Message();

	//从给定Folder集合中添加/删除本Message
	void save(Folder&);

	void remove(Folder&);

	//向给定的folders中加入folder或删除指定的folder
	void Add(Folder&);	

	void REM(Folder&);

};

void Message::Add(Folder& f)
{
	folders.insert(&f);
}

void Message::REM(Folder& f)
{
	if (folders.find(&f) != folders.end())	folders.erase(&f);
}

void Message::save(Folder& f)
{
	folders.insert(&f);
	f.addMsg(this);
}



void Message::remove(Folder& f)
{
	folders.erase(&f);
	f.remMsg(this);
}


void Message::add_to_Folders(const Message &m)
{
	for (auto f : m.folders)
		f->addMsg(this);
}

Message::Message(const Message &m):contents(m.contents),folders(m.folders)
{
	add_to_Folders(m);			//拷贝构造函数,会将副本也添加到之前的folders中
}

void Message::remove_from_Folders()
{
	for (auto f : folders)
		f->remMsg(this);
}

Message::~Message()
{
	remove_from_Folders();	//要保证删除此message,之前所有存储它的folder的记录也得删除
							//set 和string 自带析构函数
}

Message& Message::operator=(const Message &rhs)
{
	remove_from_Folders();
	contents = rhs.contents;
	folders = rhs.folders;
	add_to_Folders(rhs);
	return *this;
}

void swap(Message &lhs, Message&rhs)
{
	using std::swap;
	for (auto f : lhs.folders)
		f->remMsg(&lhs);
	for (auto f : rhs.folders)
		f->remMsg(&rhs);
	swap(lhs.contents, rhs.contents);
	swap(lhs.folders, lhs.folders);
	for (auto f : lhs.folders)
		f->addMsg(&lhs);
	for (auto f : rhs.folders)
		f->addMsg(&rhs);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值