13.4 Message, Folder类的实现

Message.h

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

class Folder;

class Message {
    friend class Folder;
    friend void swap(Message &lhs, Message &rhs);
public:
    explicit Message(const std::string &s)
        : m_content(s) {}
    Message(const Message &m);
    Message &operator=(const Message &m);
    Message(Message &&); // 不声明为noexcept是因为会执行insert,有可能会有bad_alloc异常
    Message &operaor=(Message &&);
    ~Message();
    void save(Folder&);
    void remove(Folder&);

    void addFld(Folder *);
    void remFld(Folder *);

private:
    std::set<Folder *> m_folders;
    std::string m_content;

    void add_to_folders(Message &);
    void remove_from_folders();

	void move_folders(Message *);

public:
    void debug_print();
};

Message.cpp

#include "Message.h"

Message::Message(const Message &m)
    : m_folders(m.m_folders), m_content(m.m_content) {
        add_to_folders(*this);
    }

Message &Message::operator=(const Message &m) {
    remove_from_folders();
    m_folders = m.m_folders;
    m_content = m.m_content;
    add_to_folders(*this);
    return *this;
}

Message::Message(Message &&obj) : m_content(std::move(obj.m_content) {
	move_folders(&obj); 
}

Message &operaor=(Message &&m) {
	if (this != &m) {
		remove_from_folders();
		move_folders(&m);
		m_content = std::move(m.m_content);
	}
	return *this;
}

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

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

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

void Message::add_to_folders(Message &m) {
    for (auto &i:m_folders) {
        i->addMsg(&m);
    }
}

void Message::remove_from_folders() {
    for (auto &i:m_folders) {
        i->remMsg(this);
    }
}

void Message::move_folders(Message *m) {
	m_folders = std::move(m->m_folders);
	for (auto &f:m_folders) {
		f->remMsg(m);
		f->addMsg(this);
	}
	m->clear();
}

void swap(Message &lhs, Message &rhs) {
    for (auto m:lhs.m_folders) {
        m->remMsg(&lhs);
    }
    for (auto m:rhs.m_folders) {
        m->remMsg(&rhs);
    }
    using std::swap;
    swap(lhs.m_content, rhs.m_content);
    swap(lhs.m_folders, rhs.m_folders);
    for (auto i:lhs.m_folders) {
        i->addMsg(&lhs);
    }
    for (auto i:rhs.m_folders) {
        i->addMsg(&rhs);
    }
}

void Message::addFld(Folder *f) {
    m_folders.insert(f);
}

void Message::remFld(Folder *f) {
    m_folders.erase(f);
}

void Message::debug_print()
{
    std::cout << "Message:\n\t" << m_content << std::endl;
    std::cout << "Appears in " << m_folders.size() << " Folders" << std::endl;
}

Folder.h

#pragma once
#include <iostream>
#include <string>
#include <set>
#include "Message.h"

class Message;

class Folder {
    friend class Message;
    friend void swap(Folder &lhs, Folder &rhs);
public:
    Folder() : m_msgs(), m_name() {}
    explicit Folder(const std::string &s)
        : m_msgs(), m_name(s) {}
    Folder(const Folder& f);
    Folder &operator=(const Folder&);

    void add_to_message(Folder &);
    void remove_from_message();

    void addMsg(Message *);
    void remMsg(Message *);

    void save(Message &m);
    void remove(Message &m);

private:
    std::set<Message *> m_msgs;
    std::string m_name;

public:
    void debug_print();
};

Folder.cpp

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

Folder::Folder(const Folder &f)
    : m_msgs(f.m_msgs), m_name(f.m_name) {}

Folder &Folder::operator=(const Folder &f) {
    remove_from_message();
    m_msgs = f.m_msgs;
    m_name = f.m_name;
    add_to_message(*this);
    return *this;
}

void Folder::add_to_message(Folder &f) {
    for (auto i:m_msgs) {
        i->addFld(&f);
    }
}

void Folder::remove_from_message() {
    while (!m_msgs.empty()) {
        (*m_msgs.begin())->remFld(this);
    }
}

void Folder::addMsg(Message *m) {
    m_msgs.insert(m);
}

void Folder::remMsg(Message *m) {
    m_msgs.erase(m);
}

void Folder::save(Message &m) {
    m_msgs.insert(&m);
    m.addFld(this);
}
void Folder::remove(Message &m) {
    m_msgs.erase(&m);
    m.remFld(this);
}

void swap(Folder &lhs, Folder &rhs) {
    for (auto f:lhs.m_msgs) {
        f->remFld(&lhs);
    }
    for (auto f:rhs.m_msgs) {
        f->remFld(&rhs);
    }
    using std::swap;
    swap(lhs.m_msgs, rhs.m_msgs);
    swap(lhs.m_name, rhs.m_name);
    for (auto f:lhs.m_msgs) {
        f->addFld(&lhs);
    }
    for (auto f:rhs.m_msgs) {
        f->addFld(&rhs);
    }
}

void Folder::debug_print()
{
    std::cout << "Folder contains " << m_msgs.size() << " messages" << std::endl;
    int ctr = 1;
    for (std::set<Message*>::iterator m = m_msgs.begin();
			m != m_msgs.end(); ++m) {
        std::cout << "Message " << ctr++ << ":\n\t" << (*m)->m_content << std::endl;
	}
}

main.cpp

#include <iostream>
#include <string>
#include <vector>
#include "Message.h"
#include "Folder.h"

using namespace std;

int main() {
    string s1("contents1");
	string s2("contents2");
	string s3("contents3");
	string s4("contents4");
	string s5("contents5");
	string s6("contents6");
	
	// all new messages, no copies yet
	Message m1(s1);
	Message m2(s2);
	Message m3(s3);
	Message m4(s4);
	Message m5(s5);
	Message m6(s6);

	Folder f1;
	Folder f2;

	m1.save(f1); m3.save(f1); m5.save(f1);
	m1.save(f2);
	m2.save(f2); m4.save(f2); m6.save(f2);
	
	m1.debug_print();
	f2.debug_print();

	// create some copies
	Message c1(m1);
	Message c2(m2), c4(m4), c6(m6);
	
	m1.debug_print();
	f2.debug_print();

	// now some assignments
	m2 = m3;
	m4 = m5;
	m6 = m3;
	m1 = m5;

	m1.debug_print();
	f2.debug_print();

	// finally, self-assignment
	m2 = m2;
	m1 = m1;

	m1.debug_print();
	f2.debug_print();

	vector<Message> vm;
	cout << "capacity: " << vm.capacity() << endl;
	vm.push_back(m1);

	cout << "capacity: " << vm.capacity() << endl;
	vm.push_back(m2);

	cout << "capacity: " << vm.capacity() << endl;
	vm.push_back(m3);

	cout << "capacity: " << vm.capacity() << endl;
	vm.push_back(m4);

	cout << "capacity: " << vm.capacity() << endl;
	vm.push_back(m5);

	cout << "capacity: " << vm.capacity() << endl;
	vm.push_back(m6);

	vector<Folder> vf;
	cout << "capacity: " << vf.capacity() << endl;
	vf.push_back(f1);

	cout << "capacity: " << vf.capacity() << endl;
	vf.push_back(f2);

	cout << "capacity: " << vf.capacity() << endl;
	vf.push_back(Folder(f1));

	cout << "capacity: " << vf.capacity() << endl;
	vf.push_back(Folder(f2));

	cout << "capacity: " << vf.capacity() << endl;
	vf.push_back(Folder());

	Folder f3;
	f3.save(m6);
	cout << "capacity: " << vf.capacity() << endl;
	vf.push_back(f3);

    return 0;
}

Result:

Message:
        contents1
Appears in 2 Folders
Folder contains 4 messages
Message 1:
        contents1
Message 2:
        contents2
Message 3:
        contents4
Message 4:
        contents6
Message:
        contents1
Appears in 2 Folders
Folder contains 8 messages
Message 1:
        contents1
Message 2:
        contents2
Message 3:
        contents4
Message 4:
        contents6
Message 5:
        contents1
Message 6:
        contents2
Message 7:
        contents4
Message 8:
        contents6
Message:
        contents5
Appears in 1 Folders
Folder contains 4 messages
Message 1:
        contents1
Message 2:
        contents2
Message 3:
        contents4
Message 4:
        contents6
Message:
        contents5
Appears in 1 Folders
Folder contains 4 messages
Message 1:
        contents1
Message 2:
        contents2
Message 3:
        contents4
Message 4:
        contents6
capacity: 0
capacity: 1
capacity: 2
capacity: 4
capacity: 4
capacity: 8
capacity: 0
capacity: 1
capacity: 2
capacity: 4
capacity: 4
capacity: 8

对于m2 = m3; m4 = m5; m6 = m3; m1 = m5;这一段的结果和我期望的不一致,需要再看一下。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值