首页 > 代码库 > 【足迹C++primer】45、拷贝控制示例

【足迹C++primer】45、拷贝控制示例

拷贝控制示例

那么接下来尽情欣赏这个案例吧!!!

/**
* 功能:拷贝控制示例
* 时间:2014年7月14日10:57:39
* 作者:cutter_point
*/

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

using namespace std;

class Folder;
/**
Message类
*/
class Message
{
    friend void swap(Message&, Message&);
    friend class Folder;
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&);
    //显示有几个Message对象
    void show();
private:
    string contents;        //实际消息文本
    set<Folder*> folders;   //包含本Message的folder
    //拷贝构造函数,拷贝赋值运算符合析构函数所使用的工具函数
    //将本message添加到指向参数的folder中
    void add_to_Folders(const Message&);
    //从folders中的每个Folder中删除本Message
    void remove_from_Folders();
    //向folders添加和删除
    void addFldr(Folder *f){folders.insert(f);}
    void remFldr(Folder *f){folders.erase(f);}
};

/**
Folder类
*/
class Folder
{
    friend void swap(Message&, Message&);
    friend class Message;
public:
    //构造函数
    Folder()=default;
    //拷贝构造函数
    Folder(const Folder&);
    //拷贝赋值运算符
    Folder & operator=(const Folder&);
    //析构函数
    ~Folder();

    //对应的save和remove函数
    void save(Message&);
    void remove(Message&);

    //显示有几个Message
    void show();

private:
    set<Message*> msgs;         //用来保存当前Folder保存的各种Message对象
    //拷贝构造函数,拷贝赋值运算符合析构函数所使用的工具函数
    //将本message添加到指向参数的folder中
    void add_to_Message(const Folder&);
    //从folders中的每个Folder中删除本Message
    void remove_from_Message();
    void addMsg(Message *m){msgs.insert(m);}       //添加一个对象
    void remMsg(Message *m){msgs.erase(m);}

};

/**
展示有几个set成员
*/
void Message::show()
{
    cout<<"folders的个数有:"<<folders.size()<<endl;
}

void Folder::show()
{
    cout<<"msgs的个数有:"<<msgs.size()<<endl;
}

/**
save和remove成员
*/
void Folder::save(Message &m)
{
    msgs.insert(&m);
    m.addFldr(this);
}

void Message::save(Folder &f)
{
    folders.insert(&f);     //将给定Folder添加到我们的Folder列表中
    f.addMsg(this);         //将本Message添加到f的Message中
}

void Folder::remove(Message &m)
{
    msgs.erase(&m);
    m.remFldr(this);
}

void Message::remove(Folder &f)
{
    folders.erase(&f);      //将给定Folder从我们的Folder列表中删除
    f.remMsg(this);         //将本Message从f的Message中删除
}

/**
Message类的拷贝控制成员
*/
//将本Message添加到指向m的Folder中
void Message::add_to_Folders(const Message &m)
{
    for(auto f : m.folders)     //对每个包含m的set的folder
        f->addMsg(this);        //向Folder添加一个指向本Message的指针
}

Message::Message(const Message &m):contents(m.contents), folders(m.folders)
{
    add_to_Folders(m);
}

/**
Message的析构函数
*/
//对应的Folder中删除本Message,这个是析构函数要用到的工具函数
void Message::remove_from_Folders()
{
    for(auto f : folders)
        f->remMsg(this);        //从该Folder中删除本Message
}

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

/**
Message的拷贝赋值运算符
*/
Message& Message::operator=(const Message &rhs)
{
    //先把本对象的全部指针清空,准备接受右边的赋值
    remove_from_Folders();      //更新已有的Folder
    contents=rhs.contents;
    folders=rhs.folders;
    //将本文本添加发哦相应的Folders中
    add_to_Folders(rhs);

    return *this;
}

/**
Message的swap函数
*/
void swap(Message &lhs, Message &rhs)
{
    using std::swap;    //在本例中严格来说不需要,但是这是一个好习惯
    //将每个相应的消息从原来的Folder中删除
    for(auto f : lhs.folders)
        f->remMsg(&lhs);
    for(auto f : rhs.folders)
        f->remMsg(&rhs);

    //交换相应的数据
    swap(lhs.folders, rhs.folders); //swap(set&, set&)
    swap(lhs.contents, rhs.contents);   //swap(string&, string&)

    //将每个Message的指针添加到它的(新)Folder中,已经交换了
    for(auto f : lhs.folders)
        f->addMsg(&lhs);
    for(auto f : rhs.folders)
        f->addMsg(&rhs);
}

/**
Folder的拷贝构造,拷贝赋值运算符,析构函数定义
*/
void Folder::add_to_Message(const Folder &f)
{
    for(auto m : f.msgs)
        m->addFldr(this);
}

Folder::Folder(const Folder &f):msgs(f.msgs)
{
    add_to_Message(f);
}

//拷贝赋值运算符void remove_from_Message
void Folder::remove_from_Message()
{
    for(auto m : msgs)       //清除全部指针
        m->remFldr(this);
}

Folder& Folder::operator=(const Folder &rhs)
{
    //先把本对象的所有指针清空
    remove_from_Message();
    msgs=rhs.msgs;

    //赋值完成后添加到那些message中
    add_to_Message(rhs);

    return *this;
}

//析构函数
Folder::~Folder()
{
    remove_from_Message();
}


int main()
{
    string s1("cutter_point1");
	string s2("cutter_point2");
	string s3("cutter_point3");
	string s4("cutter_point4");
	string s5("cutter_point5");
	string s6("cutter_point6");

	// 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);

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


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


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

	vector<Message> vm;
	cout << "capacity(初始vm容纳量): " << vm.capacity() << endl;
	vm.push_back(m1);

	cout << "capacity(添加m1后vm容纳量): " << vm.capacity() << endl;
	vm.push_back(m2);

	cout << "capacity(添加m2后vm容纳量): " << vm.capacity() << endl;
	vm.push_back(m3);

	cout << "capacity(添加m3后vm容纳量): " << vm.capacity() << endl;
	vm.push_back(m4);

	cout << "capacity(添加m4后vm容纳量): " << vm.capacity() << endl;
	vm.push_back(m5);

	cout << "capacity(添加m5后vm容纳量): " << vm.capacity() << endl;
	vm.push_back(m6);
	cout << "capacity(添加m6后vm容纳量): " << vm.capacity() << endl;

	vector<Folder> vf;
	cout << "capacity(初始vf容纳量): " << vf.capacity() << endl;
	vf.push_back(f1);

	cout << "capacity(添加f1后vf容纳量): " << vf.capacity() << endl;
	vf.push_back(f2);

	cout << "capacity(添加f2后vf容纳量): " << vf.capacity() << endl;
	vf.push_back(Folder(f1));

	cout << "capacity(再添加f1后vf容纳量): " << vf.capacity() << endl;
	vf.push_back(Folder(f2));

	cout << "capacity(再添加f2后vf容纳量): " << vf.capacity() << endl;
	vf.push_back(Folder());
	cout << "capacity(再添加空Folder后vf容纳量): " << vf.capacity() << endl;

	Folder f3;
	f3.save(m6);
	vf.push_back(f3);
	cout << "capacity(再添加空f3后vf容纳量): " << vf.capacity() << endl;

	cout<<"m1到m6中folders的个数:"<<endl;
	m1.show(); m2.show(); m3.show();
	m4.show(); m5.show(); m6.show();
	cout<<"f1到f3中Message的个数:"<<endl;
	f1.show(); f2.show(); f3.show();
	cout<<"c1,c2,c4,c6中folders的个数:"<<endl;
	c1.show(); c2.show();
	c4.show(); c6.show();


    return 0;
}


这个我运行出了结果,给大家看一看!!