一段程序,用于了解C++复制构造函数、赋值构造函数和vector的运行实现机制

本文详细介绍了C++中类Message与Folder的复制构造函数与赋值操作,包括如何在复制构造函数中实现消息在所有文件夹中的复制,在赋值操作中移除原有文件夹的消息并加入新的消息。通过实例演示了在向vector容器中插入对象时可能出现的多次调用复制构造函数的现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <set>
#include <cstdlib>
#include <vector>
using namespace std;

class Message;

class Folder
{
private:
        string path;
        set<Message*> message;
public:
        Folder(string p):path(p){}
        ~Folder(){};
        void AddMsg(Message*);
        void RemoveMsg(Message*);
        string GetName(){return path;}
};

class Message
{
private:
        string content;
        set<Folder*> folder;
        void PutMsgInAllFolders(const set<Folder*>&);
        void RemoveMsgFromAllFolders();
public:
       Message(const string& str = ""):content(str){}
       Message(const Message&);
       Message& operator = (const Message&);
       ~Message();
       bool Save(Folder&);
       bool Remove(Folder&);
       void AddFolder(Folder *);
       void RemoveFolder(Folder *);
       void ShowFolders();
};


//----functions in Message----------
Message::Message(const Message &msg)
:content(msg.content),folder(msg.folder)
{
       cout<<"调用复制构造函数: "<<content<<endl;
       PutMsgInAllFolders(folder);
}

Message& Message::operator = (const Message &msg)
{
       cout<<"调用赋值函数"<<endl;
       RemoveMsgFromAllFolders();
       content = msg.content;
       folder = msg.folder;
       PutMsgInAllFolders(folder);
}

Message::~Message()
{
     cout<<"析构 : "<<content<<endl;
     RemoveMsgFromAllFolders();
     cout<<"析构 : "<<content<<" 结束"<<endl;
}

void Message::PutMsgInAllFolders(const set<Folder*> &fld)
{
     cout<<"PutMsgInAllFolders"<<endl;
     for(set<Folder*>::iterator it = folder.begin() ; it != folder.end() ; ++it)
     {
             (*it)->AddMsg(this);
     }
}

void Message::RemoveMsgFromAllFolders()
{
     cout<<"RemoveMsgFromAllFolders"<<endl;
     for(set<Folder*>::iterator it = folder.begin() ; it != folder.end() ; ++it)
     {
             (*it)->RemoveMsg(this);
     }
}

bool Message::Save(Folder &fld)
{
     
     AddFolder(&fld);
     fld.AddMsg(this);
}

bool Message::Remove(Folder &fld)
{
     RemoveFolder(&fld);
     fld.RemoveMsg(this);
}

void Message::AddFolder(Folder *fld)
{
     Folder *fp = fld;
     folder.insert(fp);
}

void Message::RemoveFolder(Folder *fld)
{
     Folder *fp = fld;
     folder.erase(fp);
}

void Message::ShowFolders()
{
     cout<<"Message : "<<content<<endl;
     for(set<Folder*>::iterator it = folder.begin() ; it != folder.end() ; ++it)
     {
               cout<<(*it)->GetName()<<endl;
     }
}

//-------------------------------------------------------------------------------------------

//---functions in Folder-----------------------------

void Folder::AddMsg(Message *msg)
{
        Message *mp = msg;
        message.insert(mp);
}

void Folder::RemoveMsg(Message *msg )
{
        message.erase(msg);
}



//--------------------------------------------------------------------------------------------

int main()
{
    vector<Folder> folders;
    vector<Message> message;
    for(int i = 0 ; i != 10 ; ++i)
    {
            cout<<"input folder name: ";
            string name;
            cin>>name;
            Folder fld(name);
            folders.push_back( fld );
    }
    
    for(int i = 0 ; i != 10 ; ++i)
    {
            cout<<"Message "<<i+1<<" : ";
            string content;
            cin>>content;
            Message msg(content);                      
            for(int j = i ; j < i+5 ; ++j)
            {
                    srand(j);
                    int t = rand()%10;
                    cout<<t+1<<" ";
                    msg.Save( folders[t] );                   
            }
            cout<<endl;
            message.push_back(msg);      //使用该函数的时候可能多次调用复制构造函数!!!原因:vector要增大 
            cout<<"插入了一个message"<<endl;
            //system("pause");
    }

   for(vector<Message>::iterator it = message.begin() ; it != message.end() ; ++it)
    {
            it->ShowFolders();
    }

    Message msg = message[0];
    msg = message[1];
    msg.ShowFolders();

    system("pause");
    return 0;
}

程序在每次调用push_back的时候,都会调用复制构造函数。而由于vector可能在push_back的过程中重新分配空间以保持增长(见vector的边长增长机制),所以原有的vector中的值会出现复制的情况,因此,可能在插入某个值的时候,发现多次调用复制构造函数。而由于push_back的参数是引用类型,因此,传参的时候并不会复制,只是在插入的时候会出现复制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值