Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 消息分配运算符不使用交换_C++_C++11 - Fatal编程技术网

C++ 消息分配运算符不使用交换

C++ 消息分配运算符不使用交换,c++,c++11,C++,C++11,抱歉,如果标题有点不对劲,我不知道该用什么 因此,在这本书(C++入门第五版)中,我从C++中学习到一个问题: 我们没有使用复制和交换来定义消息分配 操作人员你为什么这么认为 我真的不知道,即使在分配同一个对象t本身时,这两者也会导致相同的结果 两个文件的main.cpp: 不使用交换 Message& Message::operator=(Message rhs) { swap(*this, rhs); return *this; } 运算符=: 使用交换进行更改:

抱歉,如果标题有点不对劲,我不知道该用什么

因此,在这本书(C++入门第五版)中,我从C++中学习到一个问题:

我们没有使用复制和交换来定义消息分配 操作人员你为什么这么认为

我真的不知道,即使在分配同一个对象t本身时,这两者也会导致相同的结果

两个文件的main.cpp:

不使用交换

Message& Message::operator=(Message rhs)
{
    swap(*this, rhs);
    return *this;
}
运算符=:

使用交换进行更改:

消息.hpp 消息和运算符=(消息);//要匹配def的新声明

Message.cpp

Message& Message::operator=(Message rhs)
{
    swap(*this, rhs);
    return *this;
}
输出为

2
1
正如两个版本所预期的那样

我真的不知道不使用swap的好处是什么,否则要做的工作会少一点

课程:

//Message.hpp
#ifndef消息\u水电站
#定义消息\u HPP
#包括
#包括
班级文件夹;
类消息
{
朋友类文件夹;
朋友无效交换(消息和,消息和);
friend std::ostream&print(std::ostream&os,const Message&m);
公众:
显式消息(const std::string&str=”“):内容(str){
~Message();
消息(const Message&);
消息和运算符=(const Message&);
作废保存(文件夹&);
作废删除(文件夹&);
私人:
std::字符串内容;
设置文件夹;
无效添加到文件夹(const Message&);
void从_文件夹中删除_();
};
std::ostream&print(std::ostream&,const Message&);
#恩迪夫
//Message.cpp
#包括“Message.hpp”
#包括“Folder.hpp”
无效交换(消息和左侧、消息和右侧)
{
使用std::swap;
用于(自动f:lhs.文件夹)
f->remMsg和lhs;
用于(自动f:rhs.文件夹)
f->remMsg和rhs;
交换(左侧文件夹、右侧文件夹);
交换(左侧目录、右侧目录);
用于(自动f:lhs.文件夹)
f->addMsg(&lhs);
用于(自动f:rhs.文件夹)
f->添加消息(&rhs);
}
无效消息::保存(文件夹(&f)
{
文件夹。插入(&f);
f、 addMsg(本);
}
无效消息::删除(文件夹(&f)
{
文件夹。删除(&f);
f、 remMsg(本);
}
无效消息::将\u添加到\u文件夹(const Message&m)
{
用于(自动f:m文件夹)
f->addMsg(本);
}
无效消息::从\u文件夹中删除\u()
{
用于(自动f:文件夹)
f->remMsg(本);
文件夹。清除();
}
消息::~Message()
{
从_文件夹中删除_();
}
消息::消息(const Message&m):内容(m.contents),文件夹(m.folders)
{
将_添加到_文件夹(m);
}
消息和消息::运算符=(常量消息和rhs)
{
从_文件夹中删除_();
contents=rhs.contents;
文件夹=rhs.folders;
将_添加到_文件夹(rhs);
归还*这个;
}
std::ostream&print(std::ostream&os、const Message&m)
{
操作系统删除(*此项);
}
}
无效文件夹::addMsg(消息*m)
{
msgs.插入(m);
}
无效文件夹::remMsg(消息*m)
{
msgs.erase(m);
}
std::ostream&print(std::ostream&os,文件夹&f)
{
用于(常数自动和m:f.msgs)
{

print(os,*m)So@KeithSmith发布了一个答案链接,我从中得到了两个答案。它们是:

练习13.38: 我们没有使用复制和交换来定义消息分配运算符。为什么您会这样认为

@Mooophy使用复制和交换是一种优雅的方式 动态分配的内存。在消息类中,未分配任何内容 因此,使用这个习语毫无意义,而且会使 由于指针指向后面,实现起来更加复杂

@pezy在这种情况下,
swap
函数是特殊的。这两个函数将是明确的
消息
的文件夹,然后交换成员,并将他们自己添加到每个文件夹中 文件夹。但是,
Message
assignment操作符只需清除自身,然后 复制成员,并将其自身添加到每个文件夹中。
rhs
不会 需要清除并添加到文件夹。因此,如果使用“复制并交换到” 定义,这将是非常低效的

基本上,Mooophy是说复制和交换用于动态分配内存,而消息类没有动态分配内存

pezy说swap是不同的,它将lhs和rhs添加到每个文件夹中,而赋值操作符只添加lhs,这更有效

我只是想感谢基思史密斯让我知道这个链接


链接:

可能
remove\u from\u Folders()
etc不做任何保证?请在此处发布相关代码。我个人不会单击粘贴箱链接,但它实际上更重要,这样StackOverflow可以在链接衰减的情况下自包含,因为我们懒得单击链接。您可以尝试从
文件夹
中删除对
消息
的引用,这将后期需要在
交换中重新指向。
。这本书是否继续回答自己的问题?答案可以在这里找到。
Message& Message::operator=(Message rhs)
{
    swap(*this, rhs);
    return *this;
}
2
1
// Message.hpp

#ifndef MESSAGE_HPP
#define MESSAGE_HPP

#include <string>
#include <set>

class Folder;

class Message
{
        friend class Folder;
        friend void swap(Message&, Message&);
        friend std::ostream& print(std::ostream &os, const Message &m);
public:
        explicit Message(const std::string &str = "") : contents(str) { }

        ~Message();

        Message(const Message&);
        Message& operator=(const Message&);

        void save(Folder&);
        void remove(Folder&);
private:
        std::string contents;
        std::set<Folder*> folders;

        void add_to_Folders(const Message&);
        void remove_from_Folders();
};

std::ostream& print(std::ostream &, const Message &);

#endif






// Message.cpp

#include "Message.hpp"
#include "Folder.hpp"

void swap(Message &lhs, Message &rhs)
{
        using std::swap;

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

void Message::save(Folder &f)
{
        folders.insert(&f);
        f.addMsg(this);
}

void Message::remove(Folder &f)
{
        folders.erase(&f);
        f.remMsg(this);
}


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

void Message::remove_from_Folders()
{
        for (auto f : folders)
                f->remMsg(this);
        folders.clear();
}


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

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

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


std::ostream& print(std::ostream &os, const Message &m)
{
        os << m.contents;
        return os;
}




// Folder.hpp

#ifndef FOLDER_HPP
#define FOLDER_HPP

#include <ostream>
#include <set>

class Message;

class Folder
{
        friend class Message;
        friend std::ostream& print(std::ostream &, Folder &);
public:
        ~Folder();

        void addMsg(Message *);
        void remMsg(Message *);
private:
        std::set<Message*> msgs;
};

std::ostream& print(std::ostream &, Folder &);

#endif




// Folder.cpp

#include "Folder.hpp"
#include "Message.hpp"

Folder::~Folder()
{
        for (auto &m : msgs)
        {
                m->remove(*this);
        }
}

void Folder::addMsg(Message *m)
{
        msgs.insert(m);
}

void Folder::remMsg(Message *m)
{
        msgs.erase(m);
}

std::ostream& print(std::ostream &os, Folder &f)
{
        for (const auto &m : f.msgs)
        {
                print(os, *m) << std::endl;
        }

        return os;
}