立此存照(20)[C++]C++ Primer(4th)消息处理示例

1.消息处理涉及到2个类,分别是Message类,和Folder类。其中同一个Message对象可以存放在多个不同的Folder对象中,同样,多个Folder类的对象也可以存放多个Message对象。

2.Message对象通过一个叫folders的set容器,通过存放Folder对象的指针,表示该Folder对象中存放有Message对象这种关系。同样,Folder对象中通过一个将messages的set容器,存放所有它正在存放的Message对象的指针,来指示这种存放关系。

3.Message对象可以通过其成员函数save,将自己另存为到一个新的Folder对象中去,之前保持的存放关系不变。

4.Message对象也可以通过其成员函数remove,删除与特定Folder对象的存放关系。

5.已知Message对象m1,通过m1调用Message的赋值构造函数得到的新Message对象m2,m2与m1拥有一样的存放关系。

6.一直Message对象m1,m2,若使用赋值操作符,进行m1 = m2,则m1失去了之前的存放关系,最终拥有了和m2一样的存放关系。

7.当调用析构函数释放m1之后,m1的存放关系也将不复存在。

8.由于Folder类的put_Folder_in_Messages,remove_Folder_from_Messages,remMsg,addMsg函数使用private访问控制权限,所以Message类要使用remMsg,addMsg接口时,必须进行友元声明。同理Message类的put_Msg_in_Folders,remove_Msg_from_Folders,addFldr,remFldr等函数使用了private访问控制权限,所以Folder要使用addFldr,remFldr修改Message类的folders容器,同样必须使用友元声明操作。

两个类中均涉及到对友元的使用,友元知识查看:http://blog.csdn.net/u011559205/article/details/41980205

完整代码:

Folder.h

#ifndef _FOLDER_H_
#define _FOLDER_H_

#include <iostream>
#include <string>
#include <set>

class Message;

class Folder{
private:
	std::string foldername;
	std::set<Message*> messages;
	//将这个对象指针,加到所有的Message对象的folders表中,
	//其中这些Message对象满足:其对象指针均在某个Folders对象的
	//messages表中
	void put_Folder_in_Messages(const std::set<Message*>&);
	//将当前对象指针,从它所关联的Message对象(关联表为messages)的folders表中删除
	void remove_Folder_from_Messages();
	//remMsg/addMsg从messages表中删除/添加特定的元素
	void remMsg(Message*);
	void addMsg(Message*);
public:
	Folder(const std::string &fname = "") :
		foldername(fname){}
	Folder(const Folder& fldr);
	Folder& operator=(const Folder& fldr);
	void displayMessages();
	std::string & getFoldername(){
		return foldername;
	}
	//从与对象关联的Message对象表中删去,该对象指针
	~Folder();
	friend Message;

};

#endif // !_FOLDER_H_

Message.h

#ifndef _MESSAGES_H_
#define _MESSAGES_H_

#include <iostream>
#include <string>
#include <set>
#include "Folder.h"

class Message {
private:
	std::string contents; // actual message text
	std::set<Folder*> folders; // Folders that have this Message
	// Utility functions used by copy constructor, assignment, and destructor:
	// Add this Message to the Folders that point to the parameter
	void put_Msg_in_Folders(const std::set<Folder*>&);
	// remove this Message from every Folder in folders
	void remove_Msg_from_Folders();
	//addFldr/remFldr从folders表中添加或删除Folder对象指针
	void addFldr(Folder*);
	void remFldr(Folder*);
public:
	// folders is initialized to the empty set automatically
	Message(const std::string &str = "") :
		contents(str) { }
	// copy control: we must manage pointers to this Message
	// from the Folders pointed to by folders
	Message(const Message&);
	Message& operator=(const Message&);
	~Message();
	void displayFolders(){
		for (std::set<Folder*>::iterator it = folders.begin();
			it != folders.end(); ++it)
		{
			std::cout << "--" << (*it)->foldername << std::endl;
		}
	}
	// add/remove this Message from specified Folder's set of messages
	void save(Folder&);
	void remove(Folder&);
	std::string & getContents(){
		return contents;
	}
	friend void Folder::put_Folder_in_Messages(const std::set<Message*>& msgs);
	friend void Folder::remove_Folder_from_Messages();
	friend void Folder::displayMessages();
};

#endif // !_MESSAGES_H_

Folder.cpp

#include <iostream>
#include <iterator>

#include "Folder.h"
#include "Message.h"

Folder::Folder(const Folder& fldr) : 
	foldername(fldr.foldername), messages(fldr.messages){
	//将该对象指针与相关Message对象关联
	put_Folder_in_Messages(fldr.messages);

}

Folder& Folder::operator=(const Folder& fldr){
	if (this != &fldr){
		//删除当前对象所关联的Message对象的folders删除当前对象指针
		remove_Folder_from_Messages();
		this->foldername = fldr.foldername;
		this->messages = fldr.messages;
		put_Folder_in_Messages(fldr.messages);
	}
	return *this;
}

Folder::~Folder(){
	remove_Folder_from_Messages();
}

void Folder::put_Folder_in_Messages(const std::set<Message*>& msgs){
	for (std::set<Message*>::iterator iter = msgs.begin();
		iter != msgs.end();
		++iter)
		(*iter)->addFldr(this);
}
void Folder::remove_Folder_from_Messages(){
	for (std::set<Message*>::iterator iter = messages.begin();
		iter != messages.end();
		++iter)
		(*iter)->remFldr(this);
}

void Folder::remMsg(Message* msg){
	std::set<Message*>::iterator iter = messages.find(msg);
	if (iter != messages.end())
		messages.erase(iter);
	else
		std::cerr << "删除出错" << std::endl;
}

void Folder::addMsg(Message* msg){
		std::pair<std::set<Message*>::iterator, bool> result 
			= messages.insert(msg);
		if (result.second == false)
			std::cout << "插入失败" << std::endl;
}

void Folder::displayMessages(){
	for (std::set<Message*>::iterator it = messages.begin();
		it != messages.end(); ++it)
	{
		std::cout << "--" << (*it)->contents << std::endl;
	}
}
Message.cpp

#include <set>
#include "Message.h"

//赋值构造函数,复制形参的folders,并将新建的
//Message对象添加到各个Folder对象中去
Message::Message(const Message &m) :
	contents(m.contents), folders(m.folders){
	// add this Message to each Folder that points to m
	put_Msg_in_Folders(folders);
}

// add this Message to Folders that point to rhs
void Message::put_Msg_in_Folders(const std::set<Folder*> &rhs)
{
	for (std::set<Folder*>::const_iterator beg = rhs.begin();
		beg != rhs.end(); ++beg)
		(*beg)->addMsg(this); // *beg points to a Folder
}

Message& Message::operator=(const Message &rhs)
{
	if (&rhs != this) {
		remove_Msg_from_Folders(); // update existing Folders
		contents = rhs.contents; // copy contents from rhs
		folders = rhs.folders; // copy Folder pointers from rhs
		// add this Message to each Folder in rhs
		put_Msg_in_Folders(rhs.folders);
	}
	return *this;
}

// remove this Message from corresponding Folders
void Message::remove_Msg_from_Folders()
{
	// remove this message from corresponding folders
	for (std::set<Folder*>::const_iterator beg =
		folders.begin(); beg != folders.end(); ++beg)
		(*beg)->remMsg(this); // *beg points to a Folder
}

Message::~Message()
{
	remove_Msg_from_Folders();
}

void Message::save(Folder& fldr){
	addFldr(&fldr);
	fldr.addMsg(this);
}

void Message::remove(Folder& fldr){
	remFldr(&fldr);
	fldr.remMsg(this);
}
void Message::addFldr(Folder* fldr){
	std::pair<std::set<Folder*>::iterator, bool> result =
		folders.insert(fldr);
	if (result.second == false)
		std::cerr << "插入失败" << std::endl;
}
void Message::remFldr(Folder* fldr){
	std::set<Folder*>::iterator iter = folders.find(fldr);
	if (iter != folders.end())
		folders.erase(fldr);
	else
		std::cerr << "删除出错" << std::endl;
}

测试代码:

测试Message类的成员函数save()

#include <iostream>
using namespace std;

#include "Message.h"
#include "Folder.h"

int main(){
	Message msg("how are you!"), msg2("I'm fine. thanks!");
	Folder fldr("10086"), fldr2("12306"), fldr3("12580");
	std::cout << "测试Message::save()" << std::endl;
	msg.save(fldr);
	msg2.save(fldr);
	msg.save(fldr2);
	msg.save(fldr3);
	std::cout << msg.getContents() << std::endl;
	msg.displayFolders();
	std::cout << msg2.getContents() << std::endl;
	msg2.displayFolders();
	std::cout << fldr.getFoldername() << std::endl;
	fldr.displayMessages();
	std::cout << fldr2.getFoldername() << std::endl;
	fldr2.displayMessages();
	std::cout << fldr3.getFoldername() << std::endl;
	fldr3.displayMessages();

	system("pause");
	return 0;
}
执行结果:

测试Message类的remove函数:

#include <iostream>
using namespace std;

#include "Message.h"
#include "Folder.h"

int main(){
	Message msg("how are you!");
	Folder fldr("10086"), fldr2("12306"), fldr3("12580");
	std::cout << "测试Message::save()" << std::endl;
	msg.save(fldr);
	msg.save(fldr2);
	msg.save(fldr3);
	msg.remove(fldr);
	std::cout << msg.getContents() << std::endl;
	msg.displayFolders();
	std::cout << fldr.getFoldername() << std::endl;
	fldr.displayMessages();
	std::cout << fldr2.getFoldername() << std::endl;
	fldr2.displayMessages();
	std::cout << fldr3.getFoldername() << std::endl;
	fldr3.displayMessages();

	system("pause");
	return 0;
}

执行结果:

测试Message类的复制构造函数:

#include <iostream>
using namespace std;

#include "Message.h"
#include "Folder.h"

int main(){
	Message msg("how are you!");
	Folder fldr("10086"), fldr2("12306"), fldr3("12580");
	std::cout << "测试Message::save()" << std::endl;
	msg.save(fldr);
	msg.save(fldr2);
	msg.save(fldr3);
	Message msg2(msg);//使用复制构造函数
	std::cout << msg.getContents() << std::endl;
	msg.displayFolders();
	std::cout << msg2.getContents() << std::endl;
	msg2.displayFolders();
	std::cout << fldr.getFoldername() << std::endl;
	fldr.displayMessages();
	std::cout << fldr2.getFoldername() << std::endl;
	fldr2.displayMessages();
	std::cout << fldr3.getFoldername() << std::endl;
	fldr3.displayMessages();

	system("pause");
	return 0;
}

执行结果:

使用赋值操作符:

#include <iostream>
using namespace std;

#include "Message.h"
#include "Folder.h"

int main(){
	Message msg("how are you!"), msg2("I'm fine, thanks!");
	Folder fldr("10086"), fldr2("12580");
	std::cout << "测试Message::save()" << std::endl;
	msg.save(fldr);
	msg2.save(fldr2);
	std::cout << msg.getContents() << std::endl;
	msg.displayFolders();
	std::cout << msg2.getContents() << std::endl;
	msg2.displayFolders();
	std::cout << fldr.getFoldername() << std::endl;
	fldr.displayMessages();
	std::cout << fldr2.getFoldername() << std::endl;
	fldr2.displayMessages();
	
	msg2 = msg;//赋值操作符
	std::cout << "赋值后" << std::endl;
	std::cout << msg.getContents() << std::endl;
	msg.displayFolders();
	std::cout << msg2.getContents() << std::endl;
	msg2.displayFolders();
	std::cout << fldr.getFoldername() << std::endl;
	fldr.displayMessages();
	std::cout << fldr2.getFoldername() << std::endl;
	fldr2.displayMessages();

	system("pause");
	return 0;
}
执行结果:

析构函数测试:

#include <iostream>
using namespace std;

#include "Message.h"
#include "Folder.h"

int main(){
	Message *msg = new Message("how are you!");
	Folder fldr("10086");
	msg->save(fldr);
	std::cout << msg->getContents() << std::endl;
	msg->displayFolders();
	std::cout << fldr.getFoldername() << std::endl;
	fldr.displayMessages();
	
	delete msg;
	std::cout << "调用析构函数后" << std::endl;
	std::cout << fldr.getFoldername() << std::endl;
	fldr.displayMessages();

	system("pause");
	return 0;
}
执行结果:

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值