C++Primer16.1.6节练习

news2024/11/24 2:56:54

练习16.28:

简易的shared_ptr代码如下

#include <iostream>
#include <vector>
#include <list>
using namespace std;


//shared_ptr模板
template<typename T>class SharedPtr {
	friend SharedPtr<T>& MakeShared(T* t);
public:
	//默认初始化
	SharedPtr() :ptr(nullptr), user(nullptr) { }
	//传入指向T的指针进行构造,防止隐式类型转换
	explicit SharedPtr(T* p = nullptr) :ptr(p), user(new size_t(1)) { }
	//拷贝构造
	SharedPtr(const SharedPtr& sp) :ptr(sp.ptr), user(sp.user)
	{
		if (user != nullptr)
		{
			++* user;
		}
	}
	//析构函数
	~SharedPtr();
	//赋值运算符
	SharedPtr& operator=(const SharedPtr&);
	//解引用运算符
	T& operator*() { return *ptr; }
	//常量版本
	T& operator*()const { return *ptr; }
	//返回指针
	T* get() { return ptr; }
	size_t use_count() { return *user; }
	bool unique()
	{
		if (use_count == 1)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

private:
	//指向T类型的指针
	T* ptr;
	//指向计数器的指针
	size_t* user;
};

//定义make_shared
template<typename T>
SharedPtr<T> MakeShared(T* t)
{
	T* ptr = t;
	return SharedPtr<T>(ptr);
}


//赋值运算符
template<typename T>
SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr& sp)
{
	if (this != sp)
	{
		if (user == nullptr)
		{
			--* user;
			if (*user == 0)
			{
				delete ptr;
				delete user;
			}
		}
		ptr = sp.ptr;
		if (sp.user != nullptr)
		{
			++* sp.user;
		}
		user = sp.user;
	}
	return *this;
}

//析构函数
template<typename T>
SharedPtr<T>::~SharedPtr()
{
	if (user != nullptr)
	{
		--* user;
		if (*user == 0)
		{
			delete ptr;
			delete user;
		}
	}
}


int main()
{
	SharedPtr<string>sp1(new string("hello"));
	SharedPtr<string>sp2 = MakeShared<string>(new string("world"));
	SharedPtr<int>sp3 = MakeShared<int>(new int(666));
	cout<<*sp1<<endl;
	cout << *sp2 << endl;
	cout << *sp3 << endl;
	
	system("pause");
	return 0;
}

结果如下:

 unique_ ptr代码如下:

#include <iostream>
#include <vector>
#include <list>
using namespace std;


//shared_ptr模板
template<typename T>class UniquePtr {
public:
	//默认初始化
	UniquePtr() :ptr(nullptr){ }
	//传入指向T的指针进行构造,防止隐式类型转换
	explicit UniquePtr(T* p) :ptr(p) { }
	//析构函数
	~UniquePtr();
	//不能拷贝,不能赋值运算符,定义为删除的函数
	UniquePtr(const UniquePtr&) = delete;
	UniquePtr& operator=(const UniquePtr&) = delete;
	//解引用运算符
	T& operator*() { return *ptr; }
	//常量版本
	T& operator*()const { return *ptr; }
	//u放弃对指针的控制权,返回指针,并将u置为空
	T* release();
	//释放u指向的对象,如果传入了内置指针,则使u指向这个对象,否则指控
	void reset();
	void reset(T* p);


private:
	//指向T类型的指针
	T* ptr;
};

//u放弃对指针的控制权,返回指针,并将u置为空
template<typename T>
T* UniquePtr<T>::release()
{
	auto temp = ptr;
	if (ptr != nullptr)
	{
		ptr == nullptr;
	}
	return temp;
}


//释放u指向的对象,如果传入了内置指针,则使u指向这个对象,否则指控
template<typename T>
void UniquePtr<T>::reset()
{
	if (ptr != nullptr)
	{
		delete ptr;
		ptr == nullptr;
	}
}


template<typename T>
void UniquePtr<T>::reset(T* p)
{
	if (ptr != nullptr)
	{
		delete ptr;
	}
	ptr = p;
}


//析构函数
template<typename T>
UniquePtr<T>::~UniquePtr()
{
	if (ptr != nullptr)
	{
		delete ptr;
	}
}


int main()
{
	UniquePtr<string>sp1(new string("hello"));
	UniquePtr<string>sp2;
	UniquePtr<int>sp3(new int(666));
	cout << *sp1 << endl;
	cout << *sp3 << endl;
	cout << endl;
	sp2.reset(new string("world"));
	sp1.release();

	system("pause");
	return 0;
}

结果为:

 

练习16.29:

#include <iostream>
#include <vector>
#include <list>
using namespace std;

//shared_ptr模板
template<typename T>class SharedPtr {
	friend SharedPtr<T>& MakeShared(T* t);
public:
	//默认初始化
	SharedPtr() :ptr(nullptr), user(nullptr) { }
	//传入指向T的指针进行构造,防止隐式类型转换
	explicit SharedPtr(T* p = nullptr) :ptr(p), user(new size_t(1)) { }
	//拷贝构造
	SharedPtr(const SharedPtr& sp) :ptr(sp.ptr), user(sp.user)
	{
		if (user != nullptr)
		{
			++* user;
		}
	}
	//析构函数
	~SharedPtr();
	//赋值运算符
	SharedPtr& operator=(const SharedPtr&);
	//解引用运算符
	T& operator*() { return *ptr; }
	//常量版本
	T& operator*()const { return *ptr; }
	//返回指针
	T* get() { return ptr; }
	size_t use_count() { return *user; }
	bool unique()
	{
		if (use_count == 1)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

private:
	//指向T类型的指针
	T* ptr;
	//指向计数器的指针
	size_t* user;
};


template<typename T, class ...Args>
SharedPtr<T>MakeShared(Args&&...args)
{
	return SharedPtr<T>(new T(std::forward<Args>(args)...));
}



//赋值运算符
template<typename T>
SharedPtr<T>& SharedPtr<T>::operator=(const SharedPtr& sp)
{
	if (this != sp)
	{
		if (user == nullptr)
		{
			--* user;
			if (*user == 0)
			{
				delete ptr;
				delete user;
			}
		}
		ptr = sp.ptr;
		if (sp.user != nullptr)
		{
			++* sp.user;
		}
		user = sp.user;
	}
	return *this;
}

//析构函数
template<typename T>
SharedPtr<T>::~SharedPtr()
{
	if (user != nullptr)
	{
		--* user;
		if (*user == 0)
		{
			delete ptr;
			delete user;
		}
	}
}


//声明,类模板与函数模板的声明
template<typename>class BlobPtr;
template<typename>class Blob;
template<typename>class SharedPtr;
template<typename T>
bool operator==(const Blob<T>&, const Blob<T>&);
template<typename T>class Blob {
	//每个Blob实例将访问权限授予用相同类型实例化的BlobPtr和相等运算符
	friend class BlobPtr<T>;
	friend class SharedPtr<T>;
	//template<typename X>friend class BlobPtr<T>;
	friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
	//template<typename X>friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
public:
	typedef T value_type;
	typedef typename std::vector<T>::size_type size_type;

	Blob();
	Blob(std::initializer_list<T>il);
	//模板构造函数
	template<typename It>Blob(It b, It e);
	size_type size()const { return (*data).size(); }
	bool empty()const { return (*data).element_type(); }
	void push_back(const T& t) { (*data).push_back(t); }
	//移动版本
	void push_back(T&& t) { (*data).push_back(std::move(t)); }
	void pop_back();
	//元素访问
	T& back()const;
	T& operator[](size_type i);

	BlobPtr<T> begin() { return BlobPtr<T>(*this); }
	BlobPtr<T> end()
	{
		auto ret = BlobPtr<T>(*this, (*data).size());
		return ret;
	}

	T& front()const;


private:
	SharedPtr<std::vector<T>>data;
	//data[i]无效,则抛出msg
	void check(size_type i, const std::string& msg)const;
};


template<typename T>
T& Blob<T>::front()const
{
	check(0, "front on empty Blob");
	return data->front();
}


//check
template<typename T>
void Blob<T>::check(size_type i, const std::string& msg)const
{
	if (i >= data->size())
	{
		throw std::out_of_range(msg);
	}
}

//back
template<typename T>
T& Blob<T>::back()const
{
	check(0, "back on empty Blob");
	return data->back();
}

//下标运算符
template<typename T>
T& Blob<T>::operator[](size_type i)
{
	check(i, "subscript out of range");
	return (*data)[i];
}

//pop函数
template<typename T>
void Blob<T>::pop_back()
{
	check(0, "pop_back on empty Blob");
	data->pop_back();
}

//构造函数
template<typename T>
Blob<T>::Blob() :data(MakeShared<std::vector<T>>()) { }

//接受initializer_list的构造函数
template<typename T>
Blob<T>::Blob(std::initializer_list<T>il) : data(MakeShared<std::vector<T>>(il)) { }

//若试图访问一个不存在的元素,BlobPtr抛出一个异常
template<typename T>class BlobPtr {
public:
	BlobPtr() :curr(0) { }
	BlobPtr(Blob<T>& a, size_t sz = 0) :wptr(a.data), curr(sz) { }
	T& operator*()const
	{
		auto p = check(curr, "dereference past end");
		return (*p)[curr];
	}
	//递增与递减
	BlobPtr& operator++();
	BlobPtr& operator--();

	BlobPtr& operator++(int);
	BlobPtr& operator--(int);

	T& deref() const;
	BlobPtr& incr();

private:
	std::shared_ptr<std::vector<T>>check(std::size_t, const std::string&)const;
	std::weak_ptr<std::vector<T>>wptr;
	std::size_t curr;
};

template<typename T>
T& BlobPtr<T>:: deref()const
{
	auto p = check(curr, "dereference past end");
	return (*p)[curr];
}

template<typename T>
BlobPtr<T>& BlobPtr<T>::incr()
{
	//递增curr,判断curr位于合理位置,不合理位置不递增
	check(curr, "incrasement past end of BlobPtr");
	++curr;
	return *this;
}



template<typename T>
BlobPtr<T>& BlobPtr<T>::operator++(int)
{
	BlobPtr ret = *this;
	++* this;
	return ret;
}

template<typename T>
BlobPtr<T>& BlobPtr<T>::operator--(int)
{
	BlobPtr ret = *this;
	--* this;
	return ret;
}

template<typename T>
BlobPtr<T>& BlobPtr<T>::operator++()
{
	check(curr, "increment past end of BlobPtr");
	++curr;
	return *this;
}

template<typename T>
BlobPtr<T>& BlobPtr<T>::operator--()
{
	check(curr, "decrement past begin of BlobPtr");
	++curr;
	return *this;
}




int main()
{
	Blob<int>b1 = { 1,2,3,4,5,6,7,8,9 };
	cout << b1.size() << endl;

	system("pause");
	return 0;
}

结果如下:

练习16.30:

见练习16.29

练习16.31:

shared_ptr是运行时绑定删除器,而unique_ptr则是编译时绑定删除器。unqiue_ptr有两个模板参数,一个是所管理的对象类型,另一个是删除器类型。因此,删除器类型是unique_ptr类型的一部分,在编译时就可知道,删除器可直接保存在unique_ptr对象中。通过这种方式,unique_ptr避免了间接调用删除器的运行时开销,而编译时还可以将自定义的删除器,如DebugDelete编译为内联形式 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/385772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker部署MySQL主从服务

一.主从同步流程关于MySQL主从复制主要同步的是binlog日志&#xff0c;涉及到三个线程&#xff0c;一个运行在主节点&#xff08;log dump thread&#xff09;&#xff0c;其余两个(I/O thread, SQL thread)运行在从节点&#xff0c;如下图所示:当主库数据发生变更时&#xff0…

【JavaWeb】EL表达式(191-202)

191.EL表达式-什么是EL表达式&#xff0c;以及它的作用 什么是 EL 表达式&#xff0c;EL 表达式的作用? EL 表达式的全称是&#xff1a;Expression Language。是表达式语言。 EL 表达式的什么作用&#xff1a;输出&#xff0c;EL 表达式主要是代替 jsp 页面中的表达式脚本在…

第三章 opengl之纹理

OpenGL纹理纹理环绕方式纹理过滤多级渐远纹理加载和创建纹理stb_image.h生成纹理纹理的应用纹理单元纹理 用stb_image.h库&#xff0c;原先用SOIL库也可以实现。 可以为每个顶点添加颜色来增加图形的细节。但是想得到一个真实的图形&#xff0c;需要足够多的顶点&#xff0c;…

定时任务调度方案——Xxl-Job

定时任务调度方案 随着系统规模的发展&#xff0c;项目的组织结构以及架构越来越复杂&#xff0c;业务覆盖的范围越来越广&#xff0c;定时任务数量日益增多&#xff0c;任务也变得越来越复杂&#xff0c;尤其是为了满足在用户体量日历增大时&#xff0c;系统能够稳定运行&…

汽车改色避坑指南

关于汽车改色&#xff0c;真的不是只看颜色看价格那么简单。 如何选择一家靠谱的改色店&#xff1f;要看这家店是否正规&#xff0c;是否有完备的售后和质保流程&#xff0c;后续剐蹭、磕碰、划痕是否可以修复&#xff1f;是否提前告知注意事项&#xff0c;以及改色后备案流程&…

浅谈车载测试之智能座舱人机交互

1、引言 目前&#xff0c;汽车不仅在动力源、驱动方式和驾驶体验上发生了变化&#xff0c;驾驶舱也告别了传统的枯燥机械和电子空间&#xff0c;智能化水平飙升&#xff0c;成为继家庭和办公室以外人们生活之后的“第三空间”。通过人脸&#xff1b;指纹识别、语音 / 手势交互…

【线程-J.U.C】

Lock J.U.C最核心组件&#xff0c;Lock接口出现之前&#xff0c;多线程的并发安全只能由synchronized处理&#xff0c;但java5之后&#xff0c;Lock的出现可以解决synchronized的短板&#xff0c;更加灵活。 Lock本质上是一个接口&#xff0c;定义了释放锁&#xff08;unlock&…

解决:centos7如何解决网络不可达和wget: 无法解析主机地址 “downloads.mysql.com”

遇到此类问题可能会有多重解决方法&#xff0c;需要一个一个的去排除。 1、查看自己的网络设置是不是设置的NAT模式&#xff0c;设置完成后再去ping一下网络地址。 2、ping一下百度看能不能拼成功&#xff0c;下图是ping成功的样式。&#xff08;如果不行继续往下走&#xff0…

牛客sql题目练习

Sql3描述 题目&#xff1a;现在运营需要查看用户来自于哪些学校&#xff0c;请从用户信息表中取出学校的去重数据。 示例:user_profile iddevice_idgenderageuniversityprovince12138male21北京大学Beijing23214male复旦大学Shanghai36543female20北京大学Beijing42315femal…

PowerShell攻击指南

文章目录一&#xff1a;PowerShell简介1.1&#xff1a;基本概念1.2&#xff1a;执行策略与绕过1.3&#xff1a;常用命令二&#xff1a;PowerSploit2.1&#xff1a;PowerSploit安装2.2&#xff1a;PowerSploit攻击实战2.2.1&#xff1a;直接shellcode反弹meterpreter shell2.2.2…

【C/C++每日一练】总目录(不断更新中...)

C/C 2023.03 20230303 1. 字符串相乘 ★★ 2. 单词拆分 II ★★★ 3. 串联所有单词的子串 ★★★ 20230302 1. 个位数是6&#xff0c;且能被3整除的五位数共有多少个&#xff1f; ☆ 2. 不同方式求n的阶乘 ★ 3. 报数游戏 ★☆ 20230301 1. 冒泡排序法排序 ★ …

视频号频出10w+,近期爆红的账号有哪些?

回顾2月&#xff0c;视频号持续放出大动作&#xff0c;不仅进行了16小时不间断的NBA全明星直播&#xff0c;还邀请国际奥委会入驻&#xff0c;分享奥运的最新资讯。视频号成为越来越多官方机构宣传推广的有效渠道。官方积极入驻&#xff0c;内容创作生态也在同步繁荣发展&#…

中村成洋《垃圾回收的算法与实现》PDF 读书笔记

观前提醒 为了能够锻炼自己&#xff0c;我会查阅大量外文不停的修改内容&#xff0c;少部分会提示成中文。 可能有误&#xff0c;请见谅 提示&#xff1a;若是觉得阅读困难&#xff0c;可以看如下内容 脚本之家可获取&#xff0c;若失效可私信浏览器的沙拉查词扩展&#xf…

Shell脚本学习指南 - 第二章入门篇

shell脚本的第一行#! #! /bin/awk -f 内核会扫描文件开头的#!后面内容&#xff0c;跳过所有空白符号&#xff0c;寻求可以用来执行程序的解释器的full path和option&#xff08;option后面的空格会识别&#xff09; ; shell用分号隔开多条语句 & 后台执行该命令&#xff…

ChatGPT解答:JavaScript保存当前网页页面图片为pdf文件或者word文件,前端用vue2,给出详细的方案和代码

ChatGPT解答&#xff1a;JavaScript保存当前网页页面图片为pdf文件或者word文件&#xff0c;前端用vue2&#xff0c;给出详细的方案和代码 ChatGPTDemo Based on OpenAI API (gpt-3.5-turbo). JavaScript保存当前网页页面图片为pdf文件或者word文件&#xff0c;前端用vue2&am…

Python 操作Redis

在 Python中我们使用 redis库来操作 Redis数据库。Redis数据库的使用命令这里就不介绍了。 需要安装 redis库。检查是否安装redis&#xff1a; pip redis 如果未安装&#xff0c;使用 pip命令安装 redis。 pip install redis #安装最新版本 一、Redis连接 Redis提供两个类 Re…

CEC2021:鱼鹰优化算法(Osprey optimization algorithm,OOA)求解CEC2021(提供MATLAB代码

一、鱼鹰优化算法简介 鱼鹰优化算法&#xff08;Osprey optimization algorithm&#xff0c;OOA&#xff09;由Mohammad Dehghani 和 Pavel Trojovsk于2023年提出&#xff0c;其模拟鱼鹰的捕食行为。 鱼鹰是鹰形目、鹗科、鹗属的仅有的一种中型猛禽。雌雄相似。体长51-64厘米…

2023年“楚怡杯“湖南省职业院校技能竞赛“网络安全”竞赛任务书

2023年“楚怡杯“湖南省职业院校技能竞赛“网络安全”竞赛任务书 一、竞赛时间 总计&#xff1a;360分钟 竞赛阶段竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略配置 A-3 流量完整性保护 A-4 事件监控 …

技术官方文档中的代码是用什么展示的?代码高亮插件总结

****内容预警****菜鸟教程***大佬绕道我们经常看到各种技术官方文档&#xff0c;有很多代码展示的区域&#xff0c;用于我们复制粘贴代码&#xff0c;比如vue 的官网当我们需要自己实现这么一个网站的时候&#xff0c;我就开始手忙脚乱&#xff0c;这到底是咋实现的&#xff1f…

如何使用ChatGPT快速构建一个网站模板?

欢迎来到令人兴奋的自然语言处理和机器学习世界&#xff01;今天&#xff0c;我们将探索 ChatGPT 的功能&#xff0c;它是由 OpenAI 公司开发的目前最先进的人工智能工具。当然&#xff0c;你也可以将其看作是一个智能机器人。ChatGPT 最令人印象深刻的功能之一是它能够根据简单…