C++primer 阅读点滴记录(一)

第十三章 复制控制:(copy control)

     复制构造函数(copy constructor)

     复制操作符(assignment operator)

 

  ps: 什么时候需要显示的定义复制控制操作:类具有指针成员,一般情况使用默认的复制控制

         有的类 需要禁止复制构造函数, iostream类就不允许复制

        类必须显示的声明其复制构造函数为private

最佳实践: 一般来说,最好显示或隐式定义默认构造函数和复制构造函数,只有不存在其他构造函数是才合成默认构造函数,如果定义了复制构造函数,也必须定义默认构造函数

 

//示例代码:

//copy constructor :

  Sales_item(const Sales_item& orig):

        isbn(orig.isbn),

        units_sold(orig.units_sold),

        revenue(orig.revenue){}

//assignment operator:

  Sales_item& operator=(const Sales_items& rhs)





Sales_item& Sales_item::operator=(const Sales_item& rhs){

    isbn = rhs.isbn;

    units_sold = rhs.units_sold;

    revenue = rhs.revenue;

    return *this;

}

 

注解: 实际上,应该将复制和赋值两个操作看作一个单元。 如果需要其中一个,我们几乎也肯定需要另一个。

  13.3 析构函数(destructor)

   何时调用析构函数:

/*

 * 撤销类对象时会自动调用析构函数

 * 动态分配的对象只有在指向该对象的指针被删除时才撤销

 */

void destructor_test(){

    Sales_item* p = new Sales_item; 

    {//new scope

        Sales_item item(*p);//copy constructor copies *p into item

        delete p;//destructor called on object pointed to by p

    }//exit local scope; destructor called on item

}
提示: 如果类需要析构函数,则它也需要赋值操作符和复制构造函数,这是一个有用的经验法则。这个规则常称为三法则(rule of three),指的是如果需要析构函数,则需要所有这三个幅值控制成员。

 

注解: 撤销内置类型成员或复合类型的成员没什么影响。 尤其是,合成析构函数并不删除指针成员所指向的对象。(ps:所以 有指针对象成员的类 需要析构函数,需要复制构造函数 赋值操作符)

 

消息实例  演示复制控制

#ifndef MESSAGE_H

#define MESSAGE_H

#pragma once

#include <string>

#include <iostream>

#include <set>



using namespace std;



class Message;



class Folder{

public:

    Folder(const string& s):folder_name(s){}

    Folder(const Folder&);

    Folder& operator=(const Folder&);

    ~Folder();



    void save(Message&);

    void remove(Message&);



    void addMsg(Message*);

    void remMsg(Message*);

private:

    set<Message*> messages;

    string folder_name;



    void put_Fldr_in_Message(const set<Message*>&);

    void remove_Fldr_from_Message();

};



class Message

{

public:

    Message(const string& str=""):contents(str){}

    Message(const Message&);//复制构造函数

    Message& operator=(const Message&);//赋值操作符

    ~Message();



    void save(Folder&);

    void remove(Folder&);



    void addFldr(Folder*);

    void remFldr(Folder*);

private:

    string contents; //actual message text

    set<Folder*> folders;//folders that have this message

    void put_Msg_in_Folder(const set<Folder*>&);

    void remove_Msg_from_Folders();

};





#endif // !MESSAGE_H
#include "stdafx.h"

#include "Message.h"





Message::Message(const Message& m):contents(m.contents),folders(m.folders)

{

    put_Msg_in_Folder(folders);

}



void Message::put_Msg_in_Folder(const set<Folder*>& rhs){

    for(set<Folder*>::const_iterator beg = rhs.begin();

        beg != rhs.end();++beg)

        (*beg)->addMsg(this);

}

Message& Message::operator=(const Message& rhs){

    if(&rhs != this){

        remove_Msg_from_Folders();

        contents = rhs.contents;

        folders = rhs.folders;

        put_Msg_in_Folder(rhs.folders);

    }

    return *this;

}

void Message::remove_Msg_from_Folders(){

    for(set<Folder*>::const_iterator beg = folders.begin();

            beg != folders.end();++beg)

            (*beg)->remMsg(this);

}



Message::~Message()

{

    remove_Msg_from_Folders();

}



void Message::addFldr(Folder* f){

    folders.insert(f);

}



void Message::remFldr(Folder* f){

    folders.erase(f);

}



void Message::save(Folder& fldr){

    addFldr(&fldr);

    fldr.addMsg(this);

}



void Message::remove(Folder& fldr){

    remFldr(&fldr);

    fldr.remMsg(this);

}



//Folder

Folder::Folder(const Folder& f):messages(f.messages),folder_name(f.folder_name){

    put_Fldr_in_Message(f.messages);

}



void Folder::put_Fldr_in_Message(const set<Message*>& rhs){

    for(set<Message*>::const_iterator beg = rhs.begin();

            beg != rhs.end(); ++beg)

            (*beg)->addFldr(this);

}



void Folder::remove_Fldr_from_Message(){

    for (set<Message*>::const_iterator beg =messages.begin();

         beg != messages.end(); ++beg)

         (*beg)->remFldr(this);

}



Folder& Folder::operator=(const Folder& rhs){

    if(&rhs != this){

        messages = rhs.messages;

        folder_name = rhs.folder_name;

        put_Fldr_in_Message(messages);

    }

    return *this;

}



Folder::~Folder(){

    remove_Fldr_from_Message();

}



void Folder::save(Message& msg){

    addMsg(&msg);

    msg.addFldr(this);

}



void Folder::remove(Message& msg){

    remMsg(&msg);

    msg.remFldr(this);

}



void Folder::addMsg(Message* msg){

    messages.insert(msg);

}



void Folder::remMsg(Message* msg){

    messages.erase(msg);

}

你可能感兴趣的:(Prim)