[C++ primer] 第13章_拷贝、赋值、销毁 知识总结+代码实现

12 篇文章 0 订阅

13.1 拷贝、赋值与销毁

13.1.1拷贝构造函数

拷贝构造函数条件:
1. 第一个参数为自身类型的引用
2. 任何额外参数都有默认值

对于类类型的成员,会使用其拷贝构造函数来拷贝,内置类型则直接拷贝。

#include <bits/stdc++.h>
using namespace std;
int main()
{

    return 0;
}

class Sales_data {
public:
    //拷贝析构函数
    Sales_data(const Sales_data &);
private:
    string bookNo;
    int units_sold = 0;
    double revenue;
};

Sales_data::Sales_data(const Sales_data &orig):
    bookNo(orig.bookNo),
    units_sold(orig.units_sold),
    revenue(orig.revenue)
{ }

拷贝初始化使用:
1. =号赋值
2. 非引用类型参数传递
3. 返回一个非引用类型对象
4. 花括号列表初始化数组、聚合类
5. 类类型对其分配的对象初始化。push 、insert

explicit构造函数:其只能用于直接初始化,其他情况不能隐式的使用。

拷贝赋值运算符:
会将右侧值通过成员类型的拷贝赋值运算符对成员进行赋值,然后返回左侧运算对象的引用。

Sales_data& Sales_data::operator=(const Sales_data &rhs) {
    bookNo = rhs.bookNo;
    units_sold = rhs.units_sold;
    revenue = rhs.revenue;
    return *this;
}

13.2 拷贝控制和资源管理

一但一个类需要析构函数,那么它几乎肯定也需要一个拷贝构造函数和一个拷贝赋值运算符。

为定义这些函数,我们

#include <bits/stdc++.h>
using namespace std;


class Folder;

class Message {
    friend void swap(Message& ,Message&);
    friend class Folder;
public:
    explicit Message(const string &str = ""):
            contents(str){}
    Message(const Message&);
    Message& operator=(const Message&);
    ~Message();
    void save(Folder &f);
    void remove(Folder &f);
    void debug_print();
private:
    string contents;
    set<Folder*> folders;
    void add_to_Folders(const Message&);
    void remove_from_Folders();
    void addFldr(Folder *f){folders.insert(f);}
    void remFldr(Folder *f){folders.erase(f);}

};

void swap(Message&,Message&);

class Folder {
    friend void swap(Message&,Message&);
    friend class  Message;
public:
    ~Folder();
    Folder(const Folder&);
    Folder&operator=(const Folder&);
//    Folder(Folder&&);
//    Folder&operator=(Folder&&);

    Folder()= default;
    void save(Message&);
    void remove(Message&);
    void debug_print();

private:
    set<Message*> msgs;
    void add_to_Messages(const Folder&);
    void remove_from_Msgs();
    void addMsg(Message *m){msgs.insert(m);}
    void remMsg(Message *m){msgs.erase(m);}
//    void move_Messages(Folder*);
};





/*message -> floder*/
void Folder::add_to_Messages(const Folder &f) {
    for(auto msg : f.msgs)
        msg->addFldr(this);
}

/*all msg - this folder*/
void Folder::remove_from_Msgs() {
    while(!msgs.empty())
    {
        (*msgs.begin())->remove(*this);
    }
}


Folder::Folder(const Folder &m) :
        msgs(m.msgs)
{
    add_to_Messages(m);
}


//拷贝赋值运算符
Folder& Folder::operator=(const Folder &rhs) {
    remove_from_Msgs();
    msgs = rhs.msgs;
    add_to_Messages(rhs);
}



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



/*fold ->  message , message -> fold*/
void Folder::save(Message &m) {
    msgs.insert(&m);
    m.addFldr(this);
}


/*fold - message ,message - fold*/
void Folder::remove(Message &m) {
    msgs.erase(&m);
    m.remFldr(this);
}


void Folder::debug_print() {
    cerr<<"there are "<<msgs.size()<<"message in this folder."<<endl;
}


/*************************************/






/*message->folder, folder->message*/
void Message::save(Folder &f) {
    folders.insert(&f);
    f.addMsg(this);
}
/*message - folder , folder - message*/
void Message::remove(Folder &f) {
    folders.erase(&f);
    f.remMsg(this);
}

/*all folder -> message*/
void Message::add_to_Folders(const Message &m) {
    for(auto f:m.folders)
    {
        f->addMsg(this);
    }
}

//remove this Message
/*all folder - message*/
void Message::remove_from_Folders() {
    for(auto f : folders)
        f->remMsg(this);
}

Message::Message(const Message &m):
        contents(m.contents),folders(m.folders)
{
    /*把this添加到对应folder中*/
    add_to_Folders(m);
}

//从所有的message删除
Message::~Message() {
    remove_from_Folders();
}

Message& Message::operator=(const Message &rhs){
//    delete *this
    remove_from_Folders();
    contents = rhs.contents;
    folders = rhs.folders;
    /*add this to folders*/
    add_to_Folders(rhs);
    return *this;
}

void Message::debug_print() {
    cerr << "Message\t"<<contents<<endl;
    cerr<<"Appers in" << folders.size()<<" Folders"<<endl;
}

void swap(Message &lhs, Message &rhs)
{
    for(auto f : lhs.folders)
        f->remMsg(&lhs);
    for(auto f : rhs.folders)
        f->remMsg(&rhs);
    swap(lhs.folders,rhs.folders);
    swap(lhs.contents,rhs.contents);
    for(auto f : lhs.folders)
        f->addMsg(&lhs);
    for(auto f : rhs.folders)
        f->addMsg(&rhs);
}












int main() {
    string s1("contents1");
    string s2("contents2");
    string s3("contents3");
    string s4("contents4");
    string s5("contents5");
    string s6("contents6");

    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.debug_print();
//    m2.debug_print();
//    f1.debug_print();
/*m1,m3,m5*/
    Message c1(m1);
    Message c2(m3);

//    m1.debug_print();
//    f2.debug_print();
// m1,m3,m5,c1,c2
//    f1.debug_print();
    m1 = m5;

    swap(m1,m4);

//m5,m3,m5,c1,c2
    m1.debug_print();
    f1.debug_print();

    return 0;
}

动态内存管理类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值