Skip to content

Commit

Permalink
ch13 ex13.34
Browse files Browse the repository at this point in the history
  • Loading branch information
huangmingchuan committed Feb 26, 2016
1 parent cd2b717 commit cf28223
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 3 deletions.
12 changes: 9 additions & 3 deletions ch13/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,23 +209,29 @@ pravite:

> 解释 swap(HasPtr&, HasPtr&)中对 swap 的调用不会导致递归循环。
## 练习13.30
这其实是3个不同的函数,参数类型不一样,所以不会导致递归循环。

## [练习13.30](exercise13_30.h)

> 为你的类值版本的 HasPtr 编写 swap 函数,并测试它。为你的 swap 函数添加一个打印语句,指出函数什么时候执行。
## 练习13.31
## [练习13.31](exercise13_31.h)

> 为你的 HasPtr 类定义一个 < 运算符,并定义一个 HasPtr 的 vector。为这个 vector 添加一些元素,并对它执行 sort。注意何时会调用 swap。
## 练习13.32

> 类指针的 HasPtr 版本会从 swap 函数收益吗?如果会,得到了什么益处?如果不是,为什么?
会。交换指针不用进行内存分配,因此得到了性能上的提升。

## 练习13.33

> 为什么Message的成员save和remove的参数是一个 Folder&?为什么我们不能将参数定义为 Folder 或是 const Folder?
## 练习13.34
因为 save 和 remove 操作需要更新指定 Folder。

## 练习13.34 : [h](exercise13_34.h) | [cpp](exercise13_34.cpp)

> 编写本节所描述的 Message。
Expand Down
41 changes: 41 additions & 0 deletions ch13/exercise13_30.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef CP5_ex13_11_h
#define CP5_ex13_11_h

#include <string>
#include <iostream>

class HasPtr
{
public:
friend void swap(HasPtr&, HasPtr&);
HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) {}
HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) {}
HasPtr& operator=(const HasPtr &hp)
{
auto new_p = new std::string(*hp.ps);
delete ps;
ps = new_p;
i = hp.i;
return *this;
}
~HasPtr()
{
delete ps;
}

void show() { std::cout << *ps << std::endl; }
private:
std::string *ps;
int i;
};

inline
void swap(HasPtr& lhs, HasPtr& rhs)
{
using std::swap;
swap(lhs.ps, rhs.ps);
swap(lhs.i, rhs.i);
std::cout << "call swap(HasPtr& lhs, HasPtr& rhs)" << std::endl;
}

#endif
59 changes: 59 additions & 0 deletions ch13/exercise13_31.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef CP5_ex13_31_h
#define CP5_ex13_31_h

#include <string>
#include <iostream>

class HasPtr
{
public:
friend void swap(HasPtr&, HasPtr&);
friend bool operator<(const HasPtr &lhs, const HasPtr &rhs);

HasPtr(const std::string &s = std::string())
: ps(new std::string(s)), i(0)
{}

HasPtr(const HasPtr &hp)
: ps(new std::string(*hp.ps)), i(hp.i)
{}

HasPtr& operator=(HasPtr tmp)
{
this->swap(tmp);
return *this;
}

~HasPtr()
{
delete ps;
}

void swap(HasPtr &rhs)
{
using std::swap;
swap(ps, rhs.ps);
swap(i, rhs.i);
std::cout << "call swap(HasPtr &rhs)" << std::endl;
}

void show() const
{
std::cout << *ps << std::endl;
}
private:
std::string *ps;
int i;
};

void swap(HasPtr& lhs, HasPtr& rhs)
{
lhs.swap(rhs);
}

bool operator<(const HasPtr &lhs, const HasPtr &rhs)
{
return *lhs.ps < *rhs.ps;
}

#endif
122 changes: 122 additions & 0 deletions ch13/exercise13_34.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include "exercise13_34.h"
#include <iostream>

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

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

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

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

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

void Message::print_debug()
{
std::cout << contents << std::endl;
}

void swap(Folder& lhs, Folder& rhs)
{
using std::swap;
for (auto m : lhs.msgs)
m->remFlddr(&lhs);
for (auto m : rhs.msgs)
m->remFlddr(&rhs);

swap(lhs.msgs, rhs.msgs);

for (auto m : lhs.msgs)
m->addFldr(&lhs);
for (auto m : rhs.msgs)
m->addFldr(&rhs);
}

void Folder::add_to_Message(const Folder& f)
{
for (auto m : f.msgs)
m->addFldr(this);
}

Folder::Folder(const Folder& f) :msgs(f.msgs)
{
add_to_Message(f);
}

void Folder::remove_to_Message()
{
for (auto m : msgs)
m->remFlddr(this);
msgs.clear();
}

Folder::~Folder()
{
remove_to_Message();
}

Folder& Folder::operator=(const Folder& rhs)
{
remove_to_Message();
msgs = rhs.msgs;
add_to_Message(rhs);
return *this;
}

void Folder::print_debug()
{
for (auto m : msgs)
std::cout << m->contents << " ";
std::cout << std::endl;
}
61 changes: 61 additions & 0 deletions ch13/exercise13_34.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef ex13_34_h
#define ex13_34_h

#include <string>
#include <set>

class Folder;

class Message
{
friend void swap(Message &, Message &);
friend void swap(Folder &, Folder &);
friend class Folder;
public:
explicit Message(const std::string& s = "") :contents(s) {}
Message(const Message&);
Message& operator=(const Message&);
~Message();
void save(Folder&);
void remove(Folder&);
void print_debug();

private:
std::string contents;
std::set<Folder*> folders;

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

void addFldr(Folder* f) { folders.insert(f); }
void remFlddr(Folder* f) { folders.erase(f); }
};

void swap(Message&, Message&);

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

private:
std::set<Message*> msgs;

void add_to_Message(const Folder&);
void remove_to_Message();

void addMsg(Message* m) { msgs.insert(m); }
void remMsg(Message *m) { msgs.erase(m); }
};

void swap(Folder&, Folder&);


#endif // !ex13_34_h

0 comments on commit cf28223

Please sign in to comment.