习题13.5:
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <string>
class HasPtr{
public:
HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0){ };
HasPtr(const HasPtr &cs) :ps(new std::string(*cs.ps)), i(cs.i){ };
std::string *getp(){ return ps; };
int geti(){ return i; };
private:
std::string *ps;
int i;
};
#endif
习题13.8:
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <string>
#include <memory>
class HasPtr{
public:
HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0){ };
//拷贝构造函数
HasPtr(const HasPtr &cs) :ps(new std::string(*cs.ps)), i(cs.i){ };
//拷贝赋值运算符
HasPtr &operator=(const HasPtr &hp)
{
ps = std::make_shared<std::string>(*hp.ps);
i = hp.i;
return *this;
}
//测试用函数
std::shared_ptr<std::string> getp(){ return ps; };
int geti(){ return i; };
private:
std::shared_ptr<std::string> ps;
int i;
};
#endif
习题13.13:
#include <iostream>
#include <vector>
#include <string>
#include "HasPtr.h"
using std::cin; using std::cout; using std::endl;
#include <iostream>
#include <vector>
#include <initializer_list>
struct X {
X() { std::cout << "X()" << std::endl; }
X(const X&) { std::cout << "X(const X&)" << std::endl; }
X& operator=(const X&) { std::cout << "X& operator=(const X&)" << std::endl; return *this; }
~X() { std::cout << "~X()" << std::endl; }
};
void f(const X &rx, X x)
{
std::vector<X> vec;
vec.reserve(2);
vec.push_back(rx);
vec.push_back(x);
}
int main()//from github
{
X *px = new X;
f(*px, *px);
cout << endl;
delete px;
getchar();
return 0;
}
习题13.17:
头文件:#include <iostream>
#include <vector>
#include <string>
#include "HasPtr.h"
using std::cin; using std::cout; using std::endl;
int Numbered::i = 0;
void f(const Numbered &s)
{
cout << s.mysn << endl;
}
int main()
{
Numbered a, b = a, c = b;
f(a); f(b); f(c);
getchar();
return 0;
}
源文件:
#include <iostream>
#include <vector>
#include <string>
#include "HasPtr.h"
using std::cin; using std::cout; using std::endl;
int Numbered::i = 0;
void f(const Numbered &s)
{
cout << s.mysn << endl;
}
int main()
{
Numbered a, b = a, c = b;
f(a); f(b); f(c);
getchar();
return 0;
}
习题13.18:
头文件
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl;
using std::string;
class Employee{
public:
Employee(){ id = num++; cout << id << endl; };
Employee(const string &n) :name(n){ id = num++; cout << id << endl; };
private:
string name;
unsigned int id;
static unsigned int num;
};
#endif
cpp:
#include <iostream>
#include <vector>
#include <string>
#include "Employee.h"
using std::cin; using std::cout; using std::endl;
unsigned int Employee::num = 1;
int main()
{
Employee e1("aa");
Employee e2;
getchar();
return 0;
}
习题13.19:
//删除拷贝构造函数和拷贝赋值运算符
Employee(const Employee &) = delete;
Employee& operator=(const Employee&) = delete;
习题13.27:
h
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <string>
#include <memory>
class HasPtr{
//使用引用计数版本的HasPtr
public:
HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0), use(new std::size_t(1))
{
std::cout << "构造函数调用 引用计数为" << *use << std::endl;
};
//拷贝构造函数
HasPtr(const HasPtr &cs) :ps(new std::string(*cs.ps)), i(cs.i), use(cs.use)
{
++*use;
std::cout << "拷贝构造函数调用 引用计数为" << *use << std::endl;
};
//拷贝赋值运算符
HasPtr &operator=(const HasPtr &rhs)
{
++*rhs.use;//增加右侧的引用计数,也是处理自赋值的方法
if (--*use == 0)
{
delete ps;
delete use;
std::cout << "赋值运算符左侧引用计数为0,释放内存" << std::endl;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
std::cout << "拷贝赋值运算符 左侧引用计数为" << *use << std::endl;
return *this;
}
//析构函数
~HasPtr()
{
if (--*use == 0)
{
delete ps;
delete use;
std::cout << "引用计数为0 析构函数释放内存" << std::endl;
}
}
//测试用函数
std::string *getp(){ return ps; };
int geti(){ return i; };
private:
std::string *ps;
int i;
std::size_t *use;//引用计数
};
#endif
cpp
#include <iostream>
#include <vector>
#include <string>
#include "HasPtr.h"
using std::cin; using std::cout; using std::endl;
int main()
{
{
HasPtr hp1, hp2(hp1), hp3(hp1);
HasPtr hp4("a"), hp5 = hp4;
HasPtr hp6, hp7;
hp6 = hp7;
}
getchar();
return 0;
}
习题13.29:
Node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
#include <string>
using std::cout; using std::endl;
using std::string;
class TreeNode
{
public:
TreeNode(const string &v = string()) :value(v), count(new int(1)), left(nullptr), right(nullptr){ cout << "TreeNode constuctor called" << endl; };
TreeNode(const TreeNode &tn) :value(tn.value), count(tn.count), left(tn.left), right(tn.right){ cout << "TreeNode copy constructor called"<<endl; };
TreeNode &operator=(const TreeNode &rhs);
~TreeNode();
private:
string value;
int *count;
TreeNode *left;
TreeNode *right;
};
class BinStrTree
{
public:
BinStrTree() :root(new TreeNode()){ cout << "BinStrTree constructor called" << endl;; };
BinStrTree(const BinStrTree &bst) :root(new TreeNode(*bst.root)){ cout << "BinStrTree copy constructor called" << endl; };
BinStrTree &operator=(const BinStrTree &rhs);
~BinStrTree();
private:
TreeNode *root;
};
#endif
Node.cpp
#include "Node.h"
TreeNode::~TreeNode()
{
if (--*count == 0)
{
if (left)
{
delete left;
left = nullptr;
}
if (right)
{
delete right;
right = nullptr;
}
delete count;
count = nullptr;
cout << "TreeNode deconstructor called and delete" << endl;
}
else
cout << "TreeNode deconstructor called but not delete" << endl;
}
TreeNode &TreeNode::operator=(const TreeNode &rhs)
{
++*rhs.count;
if (--*count == 0)
{
if (left)
{
delete left;
left = nullptr;
}
if (right)
{
delete right;
right = nullptr;
}
delete count;
count = nullptr;
cout << "TreeNode operator called and lhs delete" << endl;
}
value = rhs.value;
count = rhs.count;
left = rhs.left;
right = rhs.right;
cout << "TreeNode operator called and lhs has been assigned by rhs" << endl;
return *this;
}
BinStrTree &BinStrTree::operator = (const BinStrTree &rhs)
{
auto new_root = new TreeNode(*rhs.root);
delete root;
root = new_root;
cout << "BinStrTree operator called" << endl;
return *this;
}
BinStrTree::~BinStrTree()
{
delete root;
cout << "BinStrTree deconstructor delete" << endl;
}
源.cpp
#include "Node.h"
int main()
{
{
//BinStrTree hp1, hp2(hp1),hp3(hp1);
//BinStrTree hp4, hp5 = hp4;
BinStrTree hp6, hp7;
hp6 = hp7;
}
getchar();
return 0;
}
习题13.34&36:
.h
#include "Message_Folder.h"
//Message成员实现
//存放与删除指定Folder中的本Message
void Message::save(Folder &f)
{
folders.insert(&f);
f.addMsg(this);
}
void Message::remove(Folder &f)
{
folders.erase(&f);
f.remMeg(this);
}
//添加/删除本Message所属的Folder(删去指向指定Folder的指针)
void Message::addFlder(Folder *f)
{
folders.insert(f);
}
void Message::remFlder(Folder *f)
{
folders.erase(f);
}
//拷贝构造函数及析构函数的工具函数
void Message::add_to_Folders(const Message &m)//这是拷贝用的工具函数 用来将主对象添加到参数对象所在的Folder(挂指针)
{ //这只是拷贝构造函数的一部分功能
for (auto f : m.folders) //所以对比本函数和remove_from_Folders(),遍历的对象是不同的
f->addMsg(this);
}
Message::Message(const Message &m) //此处拷贝构造函数即应用了add_to_Folders的功能
:contents(m.contents), folders(m.folders) //类似析构函数应用remove_from_Folders
{ //初始值列表完成数据成员拷贝的任务,add_to_Folders负责根据m将本Message放到Folder中
add_to_Folders(m);
}
void Message::remove_from_Folders()
{
for (auto f : folders)
f->remMeg(this);
}
Message::~Message() //contents由string类析构函数来释放,folders由set类析构函数来释放
{
remove_from_Folders();
}
//拷贝赋值运算符
Message &Message::operator=(const Message &rhs)
{
remove_from_Folders(); //1.将存储(指向)左侧对象的Folder中的Message指针删除
contents = rhs.contents; //2.数据成员的拷贝
folders = rhs.folders;
add_to_Folders(rhs); //3.根据右侧对象的folders来将赋值后的左侧对象添加到指定Folder
return *this;
}
//swap函数
void Message::swap(Message &lhs, Message &rhs)
{
using std::swap;
for (auto f : lhs.folders) //1.将各Folder中存储的指向lhs和rhs的指针删除
f->remMeg(&lhs);
for (auto f : rhs.folders)
f->remMeg(&rhs);
swap(lhs.contents, rhs.contents); //2.交换数据成员
swap(lhs.folders, rhs.folders);
for (auto f : lhs.folders)
f->addMsg(&lhs);
for (auto f : rhs.folders) //3.将交换后的lhs和rhs重新在Folder中挂入指针
f->addMsg(&rhs);
}
//Folder成员实现
void Folder::addMsg(Message *pm)
{
messages.insert(pm);
}
void Folder::remMeg(Message *pm)
{
messages.erase(pm);
}
void Folder::add_to_message(const Folder &f)
{
for (auto m : f.messages)
m->addFlder(this);
}
void Folder::remove_from_message()
{
for (auto m : messages)
m->remFlder(this);
}
拷贝构造函数
Folder::Folder(const Folder &f)
:messages(f.messages)
{
add_to_message(f);
}
//赋值运算符
Folder &Folder::operator=(const Folder &f)
{
remove_from_message();
messages = f.messages;
add_to_message(f);
return *this;
}
//析构函数
Folder::~Folder()
{
remove_from_message();
}
//swap函数
void Folder::swap(Folder &lhs, Folder &rhs)
{
using std::swap;
for (auto m : lhs.messages)
m->remFlder(&lhs);
for (auto m : rhs.messages)
m->remFlder(&rhs);
swap(lhs.messages, rhs.messages);
for (auto m : lhs.messages)
m->addFlder(&lhs);
for (auto m : rhs.messages)
m->addFlder(&rhs);
}
.cpp
#ifndef MESSAGE_FOLDER_H
#define MESSAGE_FOLDER_H
#include <string>
#include <set>
using std::string;
using std::set;
class Message
{
//在类内使用 默认private
friend class Folder;
public:
//构造函数
explicit Message(const string &s = "") :contents(s){ };
//拷贝控制成员,管理从Folder指向本Message的指针
Message(const Message &);
Message &operator=(const Message &);
~Message();
//在给定Folder中添加/删除本Message
void save(Folder &);
void remove(Folder &);
//交换函数
void swap(Message &lhs, Message &rhs);
private:
string contents;
//存储的是存储了(指向本Message对象的指针)的Folder对象的指针
set<Folder *> folders;
//将本Message添加到folders指向的Folder
void add_to_Folders(const Message &);
//将本Message从folders指向的Folder中删除
void remove_from_Folders();
//在Message中添加/删除Folder,参数为Folder类型指针
void addFlder(Folder *);
void remFlder(Folder *);
};
class Folder
{
friend class Message;
public:
Folder() = default;
Folder(const Folder &);
Folder &operator=(const Folder &);
~Folder();
void swap(Folder &, Folder &);
private:
//保存Folder中包含的指向的Message的指针
set<Message *> messages;
//在Folder中添加/删除Message,参数为Message类型指针
void addMsg(Message *);
void remMeg(Message *);
void add_to_message(const Folder &);
void remove_from_message();
};
#endif
习题13.39:
.h:
#ifndef STRVEC_H
#define STRVEC_H
#include <memory>
#include <string>
#include <utility>
class StrVec
{
public:
StrVec()
:elements(nullptr), first_free(nullptr), cap(nullptr){ };
StrVec(const StrVec &);
StrVec &operator=(const StrVec &);
~StrVec();
void push_back(std::string &);
size_t size()const{ return first_free - elements; }
size_t capacity()const{ return cap - elements; }
void reserve(size_t);
void resize(size_t, const std::string &);
std::string *begin()const{ return elements; }
std::string *end()const{ return first_free; }
private:
std::allocator<std::string> alloc;
std::string *elements;
std::string *first_free;
std::string *cap;
//工具函数
std::pair<std::string *, std::string *>
alloc_n_copy(const std::string *, const std::string *);
void chk_n_alloc()
{
if (size() == capacity())reallocate();
}
void free();
void reallocate();
};
#endif
.cpp:
void StrVec::reserve(size_t n)
{
if (n > capacity())
{
auto const new_data = alloc.allocate(n);
auto dest = new_data;
auto elem = elements;
for (size_t i = 0; i != n; ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = new_data;
first_free = dest;
cap = elements + n;
}
}
void StrVec::resize(size_t n, const std::string &s = std::string())
{
if (n >= size())
{
if (n > capacity())
reserve(n);
for (size_t cnt = n - size(); cnt != 0; --cnt)
alloc.construct(first_free++, s);
}
else
{
for (auto p = first_free; p != elements + n;)
alloc.destroy(--p);
}
}
习题13.49:
StrVec.cpp:
//移动构造&移动赋值
StrVec::StrVec(StrVec &&rhs)NOEXCEPT
:elements(rhs.elements), first_free(rhs.first_free), cap(rhs.cap)
{
std::cout << "移动构造函数调用" << std::endl;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
StrVec &StrVec::operator = (StrVec &&rhs)NOEXCEPT
{
std::cout << "移动赋值运算符调用" << std::endl;
if (&rhs != this)
{
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
String.cpp:
String::String(String &&rhs) NOEXCEPT
:element(rhs.element), first_free(rhs.first_free), cap(rhs.cap)
{
cout << "移动构造函数" << endl;
rhs.element = rhs.first_free = rhs.cap = nullptr;
}
String &String::operator=(String &&rhs)NOEXCEPT
{
cout << "移动赋值运算符" << endl;
if (this != &rhs)
{
free();
element = rhs.element;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.element = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
Message_Folder.cpp:
void Message::move_Folders(Message *m)
{
folders = std::move(m->folders);
for (auto f : m->folders)
{
f->remMeg(m);
f->addMsg(this);
}
m->folders.clear();
}
Message::Message(Message &&m) :contents(std::move(m.contents))
{
cout << "移动构造函数" << endl;
move_Folders(&m);
}
Message &Message::operator=(Message &&m)
{
cout << "移动赋值运算符" << endl;
if (this != &m)
{
remove_from_Folders();
contents = std::move(m.contents);
move_Folders(&m);
}
return *this;
}
习题13.55:
void push_back(std::string &&t){
data->push_back(std::move(t));
}