C++ Primer Message and Folder classes

When writing header files that contain these two classes, one problem is worth noting.

I write the Message class first and then the Folder class. These two classes need to operate on each other's members, so they should be defined as friend metaclasses. Moreover, before defining the Message class, there must be a forward declaration of the Folder class. The functions of Message useful to Folder class objects must be defined after the Folder class, otherwise they cannot be compiled (undefined, of course, they cannot be used). So the structure of the header file I wrote is: forward declaration of Folder class - definition of Message class - definition of Folder class - definition of Message functions - definition of Folder functions

#ifndef MESSAGEFOLDER
#define MESSAGEFOLDER
#include<iostream>
#include<string>
#include<set>
class Folder;   //Forward declaration
class Message
{
	friend class Folder;   //Friend class
	friend void print(const Message&);
	friend void swap(Message&, Message&);
public:
	explicit Message(const std::string &str = "") :contents(str) {}
	Message(const Message&);
	Message& operator=(const Message&);
	~Message();
	void save(Folder&);     //Save to a directory
	void remove(Folder&);    //Remove from a directory
	void addFolder(Folder&);
	void remFolder(Folder&);
private:
	std::string contents;   //text
	std::set<Folder*> folders;   //Point to the directory where the message is saved
	void add_to_Folders(const Message&);   //18 and 19 are utility functions of public operation
	void remove_from_Folders();
};

class Folder
{
	friend class Message;    //Friend class
	friend void print(const Folder&);
	friend void swap(Folder&, Folder&);
public:
	Folder() = default;
	Folder(const Folder&);
	Folder& operator=(const Folder&);
	~Folder();
	void addMsg(Message*);
	void remMsg(Message*);
private:
	std::set<Message*> messages;
};
   //Message class related function definition
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 i : m.folders)
		i->addMsg(this);
}
void Message::remove_from_Folders()
{
	for (auto i : folders)
		i->remMsg(this);
}
void Message::addFolder(Folder &f)
{
	folders.insert(&f);
}
void Message::remFolder(Folder &f)
{
	folders.erase(&f);
}
Message::Message(const Message &m) :contents(m.contents), folders(m.folders)
{
	add_to_Folders(m);
}
Message::~Message()   //The set with pointer will automatically call the set's destructor to clean up the memory
{
	remove_from_Folders();
}
Message& Message::operator=(const Message &m)
{
	remove_from_Folders();
	contents = m.contents;
	folders = m.folders;
	add_to_Folders(m);
	return *this;
}
void print(const Message &m)
{
	std::cout << m.contents << std::endl;
}
void swap(Message &m1, Message &m2)
{
	using std::swap;
	for (auto i : m1.folders)
		i->remMsg(&m1);
	for (auto i : m2.folders)
		i->remMsg(&m2);
	swap(m1.contents, m2.contents);
	swap(m1.folders, m2.folders);
	for (auto i : m1.folders)
		i->addMsg(&m1);
	for (auto i : m2.folders)
		i->addMsg(&m2);
}

     //The definition of Folder class correlation function
void Folder::addMsg(Message *m)
{
	messages.insert(m);
}
void Folder::remMsg(Message *m)
{
	messages.erase(m);
}
Folder::Folder(const Folder &f) :messages(f.messages)
{
	for (auto i : f.messages)
	{
		i->folders.insert(this);
	}
}
Folder::~Folder()
{
	for (auto i : messages)
	{
		i->folders.erase(this);
	}
}
Folder& Folder::operator=(const Folder &f)
{
	for (auto i : messages)
	{
		i->folders.erase(this);
	}
	for (auto i : f.messages)
	{
		i->folders.insert(this);
	}
	return *this;
}
void print(const Folder &f)
{
	for (auto i : f.messages)
		print(*i);
}
void swap(Folder &f1, Folder &f2)
{
	using std::swap;
	for (auto i : f1.messages)
		i->remove(f1);
	for (auto i : f2.messages)
		i->remove(f2);
	swap(f1.messages, f2.messages);
	for (auto i : f1.messages)
		i->save(f1);
	for (auto i : f2.messages)
		i->save(f2);
}
#endif // !MESSAGEFOLDER

 

Posted on Sat, 02 Nov 2019 07:02:03 -0700 by Muddy_Funster