Point global;
Point foo_bar(Point arg) //1 函数参数
{
Point local = arg, *heap = new Point(global); //2,3 赋值初始化
*heap = local;
Point pa[ 4 ] = { local, *heap }; //4,5 列表初始化
return *heap; //6 返回值
}
13.5
class HasPtr {
public:
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) {}
private:
std::string* ps;
int i;
};
13.8
class HasPtr {
public:
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& rhs_hp)
{
std::string* tmp_ps = new std::string(*rhs_hp.ps);
delete ps;
ps = tmp_ps;
i = rhs_hp.i;
}
private:
std::string* ps;
int i;
};
13.11
class HasPtr {
public:
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& rhs_hp)
{
if (this != &rhs_hp)
{
std::string* tmp_ps = new std::string(*rhs_hp.ps);
delete ps;
ps = tmp_ps;
i = rhs_hp.i;
}
return *this;
}
~HasPtr()
{
delete ps;
}
private:
std::string* ps;
int i;
};
13.13
#include
#include
#include
struct X
{
X() { std::cout << "X()" << std::endl; }
X(const X&) { std::cout << "X(const X&)" << std::endl; }
X& operator=(const X& rh)
{
std::cout << "X& operator=(const X &rh)" << std::endl;
return *this;
}
~X() { std::cout << "~x()" << std::endl; }
};
void func1(X x)
{
std::cout << "void func1(X x)" << std::endl;
}
void func2(X& x)
{
std::cout << "void func2(X &x)" << std::endl;
}
int main()
{
std::cout << "x1" << std::endl;
X x1;
func1(x1);
std::cout << "main" << std::endl;
func2(x1);
std::cout << "main" << std::endl;
X* x2 = new X();
{
std::cout << "vector" << std::endl;
std::vector<X> v;
v.reserve(2);
v.push_back(x1);
v.push_back(*x2);
}
delete x2;
std::cout << "after delete x2" << std::endl;
return 0;
}
13.17
13.14
#include
#include
#include
class numbered
{
friend void f(numbered s);
public:
numbered() : mysn(std::to_string(std::rand())) { };
~numbered() { };
private:
std::string mysn;
};
void f(numbered s)
{
std::cout << s.mysn << std::endl;
}
int main()
{
numbered a, b = a, c = b;
f(a); f(b); f(c);
return 0;
}
13.15
#include
#include
#include
class numbered
{
friend void f(numbered s);
public:
numbered() : mysn(std::to_string(std::rand())) { };
numbered(const numbered&) : mysn(std::to_string(std::rand())) { };
~numbered() { };
private:
std::string mysn;
};
void f(numbered s)
{
std::cout << s.mysn << std::endl;
}
int main()
{
numbered a, b = a, c = b;
f(a); f(b); f(c);
return 0;
}
13.16
#include
#include
#include
class numbered
{
friend void f(const numbered&);
public:
numbered() : mysn(std::to_string(std::rand())) { };
numbered(const numbered&) : mysn(std::to_string(std::rand())) { };
~numbered() { };
private:
std::string mysn;
};
void f(const numbered &s)
{
std::cout << s.mysn << std::endl;
}
int main()
{
numbered a, b = a, c = b;
f(a); f(b); f(c);
return 0;
}
13.18
#include
#include
class Employee
{
friend void print(const Employee& e);
public:
Employee() { id = n; ++n; };
Employee(const std::string& s) {
id = n;
++n; name = s;
}
private:
std::string name;
int id;
static int n;
};
void print(const Employee& e)
{
std::cout << e.name << " " << e.id << std::endl;
}
int Employee::n = 0;
int main()
{
Employee a;
Employee b("aaaa");
print(a);
print(b);
return 0;
}
13.26
StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()){}
StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)){}
StrBlob::StrBlob(const StrBlob &sb) { data = std::make_shared<std::vector<std::string>>(*sb.data); }
StrBlob &StrBlob::operator=(const StrBlob &sb) { data = std::make_shared<std::vector<std::string>>(*sb.data); return *this; }
13.27
#ifndef HASPTR_EX11_H
#define HASPTR_EX11_H
#include
class HasPtr {
public:
HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0), use(new std::size_t(1)) { }
HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) { ++* use; } //递增计数器
HasPtr& operator=(const HasPtr& rhs) {
++* rhs.use; //递增右侧运算对象的引用次数
if (-- * use == 0)
{
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this; //返回本对象
}
~HasPtr()
{
if (-- * use == 0) //计数器变为0
{
delete ps; //释放string
delete use; //释放计数器
}
}
private:
std::string* ps;
int i;
std::size_t* use;
};
#endif
13.28
#ifndef CP5_ex13_28_h
#define CP5_ex13_28_h
#include
using std::string;
class TreeNode {
public:
TreeNode() : value(string()), count(new int(1)), left(nullptr), right(nullptr) { }
TreeNode(const TreeNode& rhs) : value(rhs.value), count(rhs.count), left(rhs.left), right(rhs.right) { ++* count; }
TreeNode& operator=(const TreeNode& rhs)
{
++* rhs.count;
if (-- * count == 0) {
delete left;
delete right;
delete count;
}
value = rhs.value;
left = rhs.left;
right = rhs.right;
count = rhs.count;
return *this;
}
~TreeNode() {
if (-- * count == 0) {
delete left;
delete right;
delete count;
}
}
private:
std::string value;
int* count;
TreeNode* left;
TreeNode* right;
};
class BinStrTree {
public:
BinStrTree() : root(new TreeNode()) { }
BinStrTree(const BinStrTree& bst) : root(new TreeNode(*bst.root)) { }
BinStrTree& operator=(const BinStrTree& bst)
{
//行为像值的类
TreeNode* new_root = new TreeNode(*bst_node);
delete root;
root = new_root;
return *this;
}
~BinStrTree() { delete root; }
private:
TreeNode* root;
};
#endif
13.30
#include
#include
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
friend bool operator<(const HasPtr&, const HasPtr&);
public:
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& rhs_hp) {
auto newp = new std::string(*rhs_hp.ps);
delete ps;
ps = newp;
i = rhs_hp.i;
return *this;
}
~HasPtr()
{
delete ps;
}
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 << "swap" << std::endl;
}
bool operator<(const HasPtr& lhs, const HasPtr& rhs)
{
std::cout << "<" << std::endl;
return *lhs.ps < *rhs.ps;
}
int main()
{
HasPtr hp1("aaa"), hp2("bbb");
swap(hp1, hp2);
std::cout << "main" << std::endl;
return 0;
}
13.31
#include
#include
#include
#include
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
friend bool operator<(const HasPtr&, HasPtr&);
public:
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& rhs_hp) {
auto newp = new std::string(*rhs_hp.ps);
delete ps;
ps = newp;
i = rhs_hp.i;
return *this;
}
~HasPtr()
{
delete ps;
}
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 << "swap" << std::endl;
}
bool operator<(const HasPtr& lhs, HasPtr&rhs)
{
std::cout << "<" << std::endl;
return *lhs.ps < *rhs.ps;
}
int main()
{
HasPtr hp1("aaa"), hp2("bbb");
swap(hp1, hp2);
std::cout << "main" << std::endl;
std::vector<HasPtr> vh{ hp1,hp2 };
std::sort(vh.begin(), vh.end());
return 0;
}
13.34
#ifndef MESSAGE_H_
#define MESSAGE_H_
#include
#include
class Message
{
friend class Folder;
friend void swap(Message&, Message&);
public:
explicit Message(const std::string &str = "") : contents(str) { };
Message(const Message&);
Message& operator=(const Message&);
~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();
void addFldr(Folder *f) { folders.insert(f); }
void remFldr(Folder *f) { folders.erase(f); }
};
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);
}
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;
}
#endif
13.36
#include
#include
class Folder; //声明
class Message
{
friend class Folder;
friend void swap(Message&, Message&);
public:
explicit Message(const std::string& str = "") :contents(str) {};
Message(const Message&);
Message& operator=(const Message&);
~Message();
void save(Folder&);
void remove(Folder&);
private:
std::string contents;
std::set<Folder*> folders;
void add_to_Floders(const Message&);
void remove_from_Floders();
void addFldr(Folder* f) { folders.insert(f); }
void remFldr(Folder* f) { folders.erase(f); }
};
class Folder
{
friend class Message;
friend void swap(Folder&, Folder&);
public:
Folder() = default;
Folder(const Folder&);
Folder& operator=(const Folder&);
~Folder();
private:
std::set<Message*>msgs;
void add_to_Message(const Folder&);
void remove_from_Message();
void addMsg(Message* m) { msgs.insert(m); }
void remMsg(Message* m) { msgs.erase(m); }
};
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_Floders(const Message& m)
{
for (auto f : m.folders)
f->addMsg(this);
}
Message::Message(const Message& m) :contents(m.contents), folders(m.folders) { add_to_Floders(m); }
void Message::remove_from_Floders()
{
for (auto f : folders)
f->remMsg(this);
}
Message::~Message()
{
remove_from_Floders();
}
Message& Message::operator=(const Message& rhs)
{
remove_from_Floders();
contents = rhs.contents;
folders = rhs.folders;
add_to_Floders(rhs);
return *this;
}
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_from_Message()
{
for (auto m : msgs)
m->remFldr(this);
}
Folder::~Folder()
{
remove_from_Message();
}
Folder& Folder::operator=(const Folder& rhs)
{
remove_from_Message();
msgs = rhs.msgs;
add_to_Message(rhs);
return *this;
}
int main()
{
return 0;
}
13.40
#include
#include
#include
class StrVec
{
public:
StrVec() :elements(nullptr),first_free(nullptr),cap(nullptr) {}
StrVec(std::initializer_list<std::string>);
StrVec(const StrVec&);
StrVec& operator=(const StrVec&);
~StrVec();
void push_back(const std::string&);
size_t size()const { return first_free - elements; }
size_t capacity()const { return cap - elements; }
std::string* begin() const { return elements; };
std::string* end() const { return first_free; };
void reserve(size_t n);
void resize(size_t n);
void resize(size_t n, const std::string& s);
private:
std::allocator<std::string> alloc;
void check_n_alloc() { if (size() == capacity())reallocate(); }
std::pair<std::string*, std::string*> alloc_n_copy(const std::string*, const std::string*);
void free();
void reallocate();
std::string* elements;
std::string* first_free;
std::string* cap;
};
StrVec::StrVec(std::initializer_list<std::string> i1)
{
auto newdata = alloc_n_copy(i1.begin(), i1.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
void StrVec::push_back(const std::string& s)
{
check_n_alloc();
alloc.construct(first_free++, s);
}
std::pair<std::string*, std::string*>StrVec::alloc_n_copy(const std::string* b, const std::string* e)
{
auto data = alloc.allocate(e - b);
return {data,uninitialized_copy(b,e,data)};
}
void StrVec::free()
{
if (elements)
{
for (auto p = first_free; p != elements;)
alloc.destroy(--p);
alloc.deallocate(elements, cap - elements);
}
}
StrVec::StrVec(const StrVec&s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::~StrVec()
{
free();
}
void StrVec::reserve(size_t n)
{
if (n <= capacity())return;
auto newdata = alloc.allocate(n);
auto dest = newdata;
auto elem = elements;
for(size_t i =0;i!=size();++i)
{
alloc.construct(dest++, std::move(*elem++));
}
free();
elements = newdata;
first_free = dest;
cap = elements + n;
}
void StrVec::resize(size_t n)
{
resize(n, std::string());
}
void StrVec::resize(size_t n, const std::string& s)
{
if (n < size())
{
while (n<size())
{
alloc.destroy(--first_free);
}
}
else if (n > size())
{
while (n>size())
{
push_back(s);
}
}
}
StrVec& StrVec::operator=(const StrVec& rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
void StrVec::reallocate()
{
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity); //分配新内存
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++)); //将数据由旧内存转移到新内存
free(); //释放旧内存
elements = newdata; //更新数据结构
first_free = dest;
cap = elements + newcapacity;
}
int main()
{
StrVec s({ "aa","bb"});
return 0;
}
13.43
std::for_each(elements, first_free, [this](std::string&p) {alloc.destroy(&p); });
第二种,更简洁;
13.44#include
#include
#include
class String
{
public:
String();
String(const char*);
String(const String&);
String& operator=(const String&);
char* begin()const { return elements; };
char* end()const{return first_free;};
~String();
private:
std::pair<char*, char*> alloc_n_copy(const char*, const char*);
void free();
std::allocator<char> alloc;
char* elements;
char* first_free;
};
std::pair<char*, char*> String::alloc_n_copy(const char* begin, const char* end)
{
char* p = alloc.allocate(end - begin);
return { p,std::uninitialized_copy(begin,end,p) };
}
String::String(const char* cp)
{
size_t n = strlen(cp);
auto newstr = alloc_n_copy(cp, cp + n);
elements = newstr.first;
first_free = newstr.second;
}
String::String()
{
String("");
}
String::String(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
elements = newstr.first;
first_free = newstr.second;
}
void String::free()
{
if (elements)
{
std::for_each(elements, first_free, [this](char cp) {alloc.destroy(&cp); });
alloc.deallocate(elements, first_free - elements);
}
}
String& String::operator=(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = newstr.first;
first_free = newstr.second;
return *this;
}
String::~String()
{
free();
}
int main()
{
return 0;
}
13.48
#include
#include
#include
#include
#include
class String
{
public:
String();
String(const char*);
String(const String&);
String& operator=(const String&);
char* begin()const { return elements; };
char* end()const{return first_free;};
~String();
private:
std::pair<char*, char*> alloc_n_copy(const char*, const char*);
void free();
std::allocator<char> alloc;
char* elements;
char* first_free;
};
std::pair<char*, char*> String::alloc_n_copy(const char* begin, const char* end)
{
char* p = alloc.allocate(end - begin);
return { p,std::uninitialized_copy(begin,end,p) };
}
String::String(const char* cp)
{
size_t n = strlen(cp);
auto newstr = alloc_n_copy(cp, cp + n);
elements = newstr.first;
first_free = newstr.second;
}
String::String()
{
String("");
}
String::String(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
elements = newstr.first;
first_free = newstr.second;
std::cout<<"String(const String& rhs)"<<std::endl;
}
void String::free()
{
if (elements)
{
std::for_each(elements, first_free, [this](char cp) {alloc.destroy(&cp); });
alloc.deallocate(elements, first_free - elements);
}
}
String& String::operator=(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = newstr.first;
first_free = newstr.second;
std::cout << "String::operator=(const String& rhs)" << std::endl;
return *this;
}
String::~String()
{
free();
}
int main()
{
std::vector<String>v;
v.push_back("aa");
v.push_back("bbb");
return 0;
}
显示被拷贝了3次(只拷贝了两次,vector有扩容)
13.49StrVec
#ifndef STRVEC_H_
#define STRVEC_H_
#include
#include
#include
#include
class StrVec
{
public:
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) { }
StrVec(std::initializer_list<std::string>);
StrVec(const StrVec&);
//移动构造函数
StrVec(StrVec&& s)noexcept :
alloc(std::move(s.alloc)),elements(std::move(s.elements)),first_free(std::move(s.first_free))
, cap(std::move(s.cap)) {
s.elements = s.first_free = s.cap = nullptr;
}
StrVec& operator=(const StrVec&);
//移动赋值函数
StrVec& operator=(StrVec&&)noexcept;
~StrVec();
void push_back(const std::string&);
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
std::string* begin() const { return elements; }
std::string* end() const { return first_free; }
void reserve(size_t n);
void resize(size_t n);
void resize(size_t n, const std::string& s);
private:
std::allocator<std::string> alloc;
void chk_n_alloc() { if (size() == capacity()) reallocate(); }
std::pair<std::string*, std::string*> alloc_n_copy(const std::string*, const std::string*);
void free();
void reallocate();
std::string* elements;
std::string* first_free;
std::string* cap;
};
StrVec::StrVec(std::initializer_list<std::string> il)
{
auto newdata = alloc_n_copy(il.begin(), il.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
void StrVec::push_back(const std::string& s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
std::pair<std::string*, std::string*> StrVec::alloc_n_copy(const std::string* b, const std::string* e)
{
auto data = alloc.allocate(e - b);
return { data, uninitialized_copy(b, e, data) };
}
void StrVec::free()
{
if (elements)
{
std::for_each(elements, first_free, [this](std::string& p) { alloc.destroy(&p); });
// for(auto p = first_free; p != elements; )
// alloc.destroy(--p);
alloc.deallocate(elements, cap - elements);
}
}
StrVec::StrVec(const StrVec& s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
StrVec::~StrVec()
{
free();
}
void StrVec::reserve(size_t n)
{
if (n <= capacity()) return;
auto newdata = alloc.allocate(n);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + n;
}
void StrVec::resize(size_t n)
{
resize(n, std::string());
}
void StrVec::resize(size_t n, const std::string& s)
{
if (n < size())
{
while (n < size())
alloc.destroy(--first_free);
}
else if (n > size())
{
while (n > size())
push_back(s);
// alloc.construct(first_free, s);
}
}
StrVec& StrVec::operator=(const StrVec& rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = cap = data.second;
return *this;
}
//移动赋值函数
StrVec& StrVec::operator=(StrVec&& rhs)noexcept
{
if (this != &rhs)
{
free();
alloc = std::move(rhs.alloc);
elements = std::move(rhs.elements);
first_free = std::move(rhs.first_free);
cap = std::move(rhs.cap);
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
}
void StrVec::reallocate()
{
auto newcapacity = size() ? 2 * size() : 1;
auto newdata = alloc.allocate(newcapacity);
auto dest = newdata;
auto elem = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(dest++, std::move(*elem++));
free();
elements = newdata;
first_free = dest;
cap = elements + newcapacity;
}
#endif
String
#ifndef STRING_H_
#define STRING_H_
#include
#include
#include
#include
class String
{
public:
String();
String(const char*);
String(const String&);
//移动构造函数
String(String&&)noexcept;
String& operator=(const String&);
//移动赋值函数
String& operator=(String&&)noexcept;
char* begin() const { return elements; }
char* end() const { return first_free; }
~String();
private:
std::pair<char*, char*> alloc_n_copy(const char*, const char*);
void free();
std::allocator<char> alloc;
char* elements;
char* first_free;
};
std::pair<char*, char*> String::alloc_n_copy(const char* begin, const char* end)
{
char* p = alloc.allocate(end - begin);
// for(auto iter = begin; iter != end; ++iter)
// alloc.construct(iter, *iter);
return{ p, std::uninitialized_copy(begin, end, p) };
}
String::String(const char* cp)
{
size_t n = strlen(cp);
auto newstr = alloc_n_copy(cp, cp + n);
elements = newstr.first;
first_free = newstr.second;
// char* p = alloc.allocate(n);
// for(int i = 0; i < n; ++i)
// alloc.construct(p+i, *(cp+i));
}
String::String()
{
String("");
}
String::String(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
elements = newstr.first;
first_free = newstr.second;
std::cout << "String(const String &rhs)" << std::endl;
}
//移动构造函数
String::String(String&& s)noexcept :alloc(std::move(s.alloc)), elements(std::move(s.elements)),first_free(std::move(s.first_free))
{
s.elements = s.first_free = nullptr;
}
void String::free()
{
if (elements)
{
std::for_each(elements, first_free, [this](char cp) { alloc.destroy(&cp); });
alloc.deallocate(elements, first_free - elements);
}
}
String& String::operator=(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = newstr.first;
first_free = newstr.second;
std::cout << "String& operator=(const String& rhs)" << std::endl;
return *this;
}
//移动赋值函数
String& String::operator=(String&& rhs)noexcept
{
if (&rhs != this)
{
free();
alloc = std::move(rhs.alloc);
elements = std::move(rhs.elements);
first_free = std::move(rhs.first_free);
rhs.elements = rhs.first_free = nullptr;
}
return *this;
}
String::~String()
{
// for(auto iter = elements; iter != first_free; )
// alloc.destroy(--iter);
free();
}
#endif
Message
#ifndef MESSAGE_H_
#define MESSAGE_H_
#include
#include
#include
class Folder;
class Message
{
friend class Folder;
friend void swap(Message&, Message&);
public:
explicit Message(const std::string& str = "") : contents(str) { };
Message(const Message&);
//Messag移动构造函数
Message(Message&& m) :contents(std::move(m.contents)) { move_Folders(&m); }
Message& operator=(const Message&);
//Messag移动赋值函数
Message& operator=(Message&&);
~Message();
void save(Folder&);
void remove(Folder&);
void move_Folders(Message*);
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 remFldr(Folder* f) { folders.erase(f); }
};
class Folder
{
friend void swap(Folder&, Folder&);
friend class Message;
public:
Folder() = default;
Folder(const Folder&);
Folder& operator=(const Folder&);
~Folder();
private:
std::set<Message*> msgs;
void add_to_Message(const Folder&);
void remove_from_Message();
void addMsg(Message* m) { msgs.insert(m); }
void remMsg(Message* m) { msgs.erase(m); }
};
void Message::move_Folders(Message* m)
{
folders = std::move(m->folders);
for (auto f : folders)
{
f->remMsg(m);
f->addMsg(this);
}
m->folders.clear();
}
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);
}
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;
}
//Messag移动赋值函数
Message& Message::operator=(Message&& rhs)
{
if (this != &rhs)
{
remove_from_Folders();
contents = std::move(rhs.contents);
move_Folders(&rhs);
}
return *this;
}
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_from_Message()
{
for (auto m : msgs)
m->remFldr(this);
}
Folder::~Folder()
{
remove_from_Message();
}
Folder& Folder::operator=(const Folder& rhs)
{
remove_from_Message();
msgs = rhs.msgs;
add_to_Message(rhs);
return *this;
}
#endif
13.50
#include
#include
#include
#include
#include
class String
{
public:
String();
String(const char*);
String(const String&);
//移动构造函数
String(String&&)noexcept;
String& operator=(const String&);
//移动赋值函数
String& operator=(String&&)noexcept;
char* begin() const { return elements; }
char* end() const { return first_free; }
~String();
private:
std::pair<char*, char*> alloc_n_copy(const char*, const char*);
void free();
std::allocator<char> alloc;
char* elements;
char* first_free;
};
std::pair<char*, char*> String::alloc_n_copy(const char* begin, const char* end)
{
char* p = alloc.allocate(end - begin);
// for(auto iter = begin; iter != end; ++iter)
// alloc.construct(iter, *iter);
return{ p, std::uninitialized_copy(begin, end, p) };
}
String::String(const char* cp)
{
size_t n = strlen(cp);
auto newstr = alloc_n_copy(cp, cp + n);
elements = newstr.first;
first_free = newstr.second;
// char* p = alloc.allocate(n);
// for(int i = 0; i < n; ++i)
// alloc.construct(p+i, *(cp+i));
}
String::String()
{
String("");
}
String::String(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
elements = newstr.first;
first_free = newstr.second;
std::cout << "String(const String &rhs)" << std::endl;
}
//移动构造函数
String::String(String&& s)noexcept :alloc(std::move(s.alloc)), elements(std::move(s.elements)), first_free(std::move(s.first_free))
{
std::cout << "String(const String &&rhs)" << std::endl;
s.elements = s.first_free = nullptr;
}
void String::free()
{
if (elements)
{
std::for_each(elements, first_free, [this](char cp) { alloc.destroy(&cp); });
alloc.deallocate(elements, first_free - elements);
}
}
String& String::operator=(const String& rhs)
{
auto newstr = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = newstr.first;
first_free = newstr.second;
std::cout << "String& operator=(const String& rhs)" << std::endl;
return *this;
}
//移动赋值函数
String& String::operator=(String&& rhs)noexcept
{
std::cout << "String& operator=(const String&& rhs)" << std::endl;
if (&rhs != this)
{
free();
alloc = std::move(rhs.alloc);
elements = std::move(rhs.elements);
first_free = std::move(rhs.first_free);
rhs.elements = rhs.first_free = nullptr;
}
return *this;
}
String::~String()
{
// for(auto iter = elements; iter != first_free; )
// alloc.destroy(--iter);
free();
}
int main()
{
std::vector<String>v1;
v1.push_back("qqq");
v1.push_back("bbb");
return 0;
}
3次移动构造(其中一次vector扩容)
13.53读取访问权限异常?!
#include
#include
#include
#include
class HasPtr {
friend void swap(HasPtr&, HasPtr&);
friend bool operator<(const HasPtr&, const HasPtr&);
public:
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( HasPtr&& hp)noexcept :ps(std::move(hp.ps)), i(std::move(hp.i)) { hp.ps = nullptr; }
HasPtr& operator=(const HasPtr& rhs_hp) {
auto newp = new std::string(*rhs_hp.ps);
delete ps;
ps = newp;
i = rhs_hp.i;
return *this;
}
//移动赋值
HasPtr& operator=(HasPtr&& rhs_hp)noexcept
{
if (this != &rhs_hp)
{
delete ps;
ps = std::move(rhs_hp.ps);
i = std::move(rhs_hp.i);
}
return *this;
}
~HasPtr()
{
delete ps;
}
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 << "swap" << std::endl;
}
bool operator<(const HasPtr& lhs, const HasPtr& rhs)
{
std::cout << "<" << std::endl;
return *lhs.ps < *rhs.ps;
}
int main()
{
HasPtr hp1("aaa"), hp2("bbb");
std::vector<HasPtr>vh{ hp1,hp2 };
std::sort(vh.begin(), vh.end());
return 0;
}
13.54
operator=不明确;
13.55
#include
#include
#include
#include
#include
#include
class ConstStrBlobPtr;
class StrBlob
{
public:
friend class ConstStrBlobPtr;
typedef std::vector<std::string>::size_type size_type;
StrBlob();
StrBlob(std::initializer_list<std::string> il);
StrBlob(const StrBlob&);
StrBlob& operator=(const StrBlob&);
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const std::string& t) { data->push_back(t); std::cout << "push_back in left_value version" << std::endl;
}
//右值版本push_back
void push_back(std::string&& t) { data->push_back(t); std::cout << "push_back in right_value version" << std::endl; }
void pop_back();
std::string& front();
std::string& back();
const std::string& front() const;
const std::string& back() const;
ConstStrBlobPtr begin();
ConstStrBlobPtr end();
private:
std::shared_ptr<std::vector<std::string>> data;
void check(size_type i, const std::string& msg) const;
};
class ConstStrBlobPtr
{
public:
ConstStrBlobPtr() : curr(0) {};
ConstStrBlobPtr(const StrBlob& a, size_t sz = 0) : wptr(a.data), curr(sz) {}
std::string& deref() const;
ConstStrBlobPtr& incr();
private:
std::shared_ptr<std::vector<std::string>> check(std::size_t, const std::string&) const;
std::weak_ptr<std::vector<std::string>> wptr;
std::size_t curr;
};
std::shared_ptr<std::vector<std::string>> ConstStrBlobPtr::check(std::size_t i, const std::string& msg) const
{
auto ret = wptr.lock();
if (!ret)
throw std::runtime_error("unbound ConstStrBlobPtr");
if (i >= ret->size())
throw std::out_of_range(msg);
return ret;
}
std::string& ConstStrBlobPtr::deref() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
ConstStrBlobPtr& ConstStrBlobPtr::incr()
{
check(curr, "increment past end of ConstStrBlobPtr");
++curr;
return *this;
}
StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {}
StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)) {}
StrBlob::StrBlob(const StrBlob& sb) { data = std::make_shared<std::vector<std::string>>(*sb.data); }
StrBlob& StrBlob::operator=(const StrBlob& sb) { data = std::make_shared<std::vector<std::string>>(*sb.data); return *this; }
void StrBlob::check(size_type i, const std::string& msg) const
{
if (i >= data->size())
throw std::out_of_range(msg);
}
std::string& StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
std::string& StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const std::string& StrBlob::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
const std::string& StrBlob::back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
ConstStrBlobPtr StrBlob::begin() { return ConstStrBlobPtr(*this); }
ConstStrBlobPtr StrBlob::end()
{
auto ret = ConstStrBlobPtr(*this, data->size());
return ret;
}
int main()
{
StrBlob b1 = { "aa","a" };
b1.push_back("aa");
return 0;
13.58
#include
#include
#include
class Foo
{
public:
Foo sorted()&&; //右值
Foo sorted() const&; ///左值引用
private:
std::vector<int >data;
};
Foo Foo::sorted()&&
{
std::cout << "Foo::sorted()&&" << std::endl;
sort(data.begin(), data.end());
return *this;
}
Foo Foo::sorted()const&
{
std::cout << "Foo::sorted()const&" << std::endl;
/*Foo ret(*this);
return ret.sorted()*/;
//死循环
return Foo(*this).sorted();
}
int main()
{
Foo foo;
foo.sorted();
return 0;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)