C++ Primer 5th笔记(chap 13 拷贝控制)实例1

1. Folder和Message的类设计

2. Messager.h

class Message {
    
    
	friend void swap(Message&, Message&);
	friend class Folder;
public:
    // folders is implicitly initialized to the empty set 
    explicit Message(const std::string &str = ""): 
		contents(str) {
    
     }  

    // copy control to manage pointers to this Message
    Message(const Message&);             // copy constructor
    Message& operator=(const Message&);  // copy assignment
    ~Message();                          // destructor
    Message(Message&&);            // move constructor
    Message& operator=(Message&&); // move assignment

    // add/remove this Message from the specified Folder's set of messages
    void save(Folder&);   
    void remove(Folder&); 
    void debug_print(); // print contents and it's list of Folders, 
                        // printing each Folder as well
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 add_to_Folders(const Message&);
	void move_Folders(Message*);
    // remove this Message from every Folder in folders
    void remove_from_Folders(); 

    // used by Folder class to add self to this Message's set of Folder's
    void addFldr(Folder *f) {
    
     folders.insert(f); }
    void remFldr(Folder *f) {
    
     folders.erase(f); }
}; 

3. save和remove

void Message::save(Folder &f)
{
    
    
    folders.insert(&f); // add the given Folder to our list of Folders
    f.addMsg(this);     // add this Message to f's set of Messages
}

void Message::remove(Folder &f)
{
    
    
    folders.erase(&f); // take the given Folder out of our list of Folders
    f.remMsg(this);    // remove this Message to f's set of Messages
}

4. folder 相关

// add this Message to Folders that point to m
void Message::add_to_Folders(const Message &m)
{
    
    
	for (auto f : m.folders) // for each Folder that holds m
        f->addMsg(this); // add a pointer to this Message to that Folder
}

// remove this Message from the corresponding Folders 
void Message::remove_from_Folders()
{
    
    
	for (auto f : folders) // for each pointer in folders
		f->remMsg(this);   // remove this Message from that Folder
	folders.clear();       // no Folder points to this Message 
}

5. 拷贝构造

Message::Message(Message &&m): contents(std::move(m.contents))
{
    
    
	move_Folders(&m); // moves folders and updates the Folder pointers
}

Message::Message(const Message &m): 
    contents(m.contents), folders(m.folders) 
{
    
    
    add_to_Folders(m); // add this Message to the Folders that point to m
}

6. 析构

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

7. 拷贝赋值

Message& Message::operator=(Message &&rhs) 
{
    
    
	if (this != &rhs) {
    
           // direct check for self-assignment
		remove_from_Folders();
		contents = std::move(rhs.contents); // move assignment
		move_Folders(&rhs); // reset the Folders to point to this Message
	}
    return *this;
}

Message& Message::operator=(const Message &rhs)
{
    
    
	// handle self-assignment by removing pointers before inserting them
    remove_from_Folders();    // update existing Folders
    contents = rhs.contents;  // copy message contents from rhs
    folders = rhs.folders;    // copy Folder pointers from rhs
    add_to_Folders(rhs);      // add this Message to those Folders
    return *this;
}

8. swap

void swap(Message &lhs, Message &rhs)
{
    
    
	using std::swap;  // not strictly needed in this case, but good habit

	// remove pointers to each Message from their (original) respective Folders
	for (auto f: lhs.folders) 
		f->remMsg(&lhs);
	for (auto f: rhs.folders) 
		f->remMsg(&rhs);

	// swap the contents and Folder pointer sets
	swap(lhs.folders, rhs.folders);   // uses swap(set&, set&)
	swap(lhs.contents, rhs.contents); // swap(string&, string&)

	// add pointers to each Message to their (new) respective Folders
	for (auto f: lhs.folders) 
		f->addMsg(&lhs);
	for (auto f: rhs.folders) 
		f->addMsg(&rhs);
}

9. 移动赋值

// move the Folder pointers from m to this Message
void Message::move_Folders(Message *m)
{
    
    
	folders = std::move(m->folders); // uses set move assignment
	for (auto f : folders) {
    
      // for each Folder 
		f->remMsg(m);    // remove the old Message from the Folder
		f->addMsg(this); // add this Message to that Folder
	}
	m->folders.clear();  // ensure that destroying m is harmless
}

【参考】
[1] 代码copyControl.h

猜你喜欢

转载自blog.csdn.net/thefist11cc/article/details/113877968