C++Primer16.4.3节练习

文章讨论了两个自定义的C++容器类StrVec和Vec,它们分别用于存储字符串和泛型类型T的对象。这两个类实现了包括默认构造、拷贝构造、赋值运算符、析构函数以及push_back方法。特别地,文章关注了emplace_back模板函数的实现,它利用转发参数来直接在容器中构建新元素,避免了额外的拷贝或移动操作。此外,还提到了内存管理策略,如内存分配、重新分配和释放。
摘要由CSDN通过智能技术生成

练习16.58:

StrVec:

#include <iostream>
#include <string>
using namespace std;
#include <vector>
#include <algorithm>
#include <set>

//类vector类内存分配策略的简化实现
class StrVec {
public:
	//默认初始化
	StrVec();
	//拷贝构造函数
	StrVec(const StrVec&);
	//拷贝赋值运算符
	StrVec& operator=(const StrVec&);
	//析构函数
	~StrVec();
	//拷贝元素
	void push_back(const std::string&);
	//数组大小和容量
	size_t size()const;
	size_t capacity()const;
	//获得数组的首元素和尾后元素
	std::string* begin()const;
	std::string* end()const;

	//emplace_back()
	template<class... Args>void emplace_back(Args&&...);

	void reserve(size_t n);
	void resize(size_t n);

private:
	//静态成员,用来分配元素
	static std::allocator<std::string>alloc;
	//工具函数,被添加元素的函数所使用
	void chk_n_alloc();
	//工具函数,被拷贝构造函数、赋值运算符和析构函数使用
	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;
};

std::allocator<string> StrVec::alloc;

//emplace_back()
template<class... Args>
inline void StrVec::emplace_back(Args&&...)
{
	chk_n_alloc();
	alloc.construct(first_free++, std:: forward<Args>(args)...);
}


int main()
{

	system("pause");
	return 0;
}

Vec:

template<typename T>class Vec {
public:
	//默认初始化
	Vec() :elements(nullptr), first_free(nullptr), cap(nullptr) { };
	//拷贝构造函数
	Vec(const Vec&);
	//拷贝赋值运算符
	Vec& operator=(const Vec&);
	Vec(initializer_list<T>);
	//析构函数
	~Vec();
	//拷贝元素
	void push_back(const T&);
	//数组大小和容量
	size_t size()const;
	size_t capacity()const;
	//获得数组的首元素和尾后元素
	T* begin()const;
	T* end()const;

	//emplace_back()
	template<class... Args>void emplace_back(Args&&...);

	void reserve(size_t n);
	void resize(size_t n);

private:
	//静态成员,用来分配元素
	static std::allocator<T>alloc;
	//工具函数,被添加元素的函数所使用
	void chk_n_alloc()
	{
		if (size() == capacity()) reallocate();
	}
	//工具函数,被拷贝构造函数、赋值运算符和析构函数使用
	std::pair<T*, T*>alloc_n_copy(const T*, const T*);
	//销毁元素并释放内存
	void free();
	//获得更多内存并拷贝已有元素
	void reallocate();
	//指向数组首元素的指针
	T* elements;
	//指向数组第一个空闲元素的指针
	T* first_free;
	//指向数组尾后位置的指针
	T* cap;
};

template<typename T>
std::allocator<T> Vec<T>::alloc;

//emplace_back()
template<typename T>
template<class... Args>
inline void Vec<T>::emplace_back(Args&&...)
{
	chk_n_alloc();
	alloc.construct(first_free++, std:: forward<Args>(args)...);
}

练习16.59:

s是一个左值,通过forward将其传入construct函数,还是一个左值。然后进行拷贝构造

练习16.60:

make_shared也是通过forward进行工作的,方式与emplace_back()类似。传入参数包,扩展,然后构造指向vector<T>的智能指针

练习16.61:

make_shared实现如下所示:


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白学C++.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值