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