c++ primer 学习笔记-第十三章

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值