c++_primer_exercise_1339

本文详细介绍了C++模板类Str_vec的实现原理及使用方法,包括构造函数、成员函数、内部实现细节等。通过实例展示了如何利用Str_vec类进行字符串数组的操作,以及其内存管理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/***********************************************
 * IDE:  VS2010
 * FILE: Str_vec.h
 ***********************************************/
#ifndef STR_VEC_H
#define STR_VEC_H

#include 
#include 	// for allocator
#include 	// for pair

class Str_vec
{
public:
	// copy control members
	Str_vec() :		// the allocator member is default initialized
	  elements(nullptr), first_free(nullptr), cap(nullptr) { }
	Str_vec(const std::string *b, const std::string *e);

	Str_vec(const Str_vec &);				// copy constructor
	Str_vec &operator=(const Str_vec &rhs);	// copy assignment
	~Str_vec() { free(); }							// destructor

	void push_back(const std::string &);	// copy the element
	
	// add elements
	size_t size() const { return first_free - elements; }  //typedef unsigned int size_t
	size_t capacity() const { return cap - elements; }

	// iterator interface
	std::string *begin() const { return elements; }
	std::string *end() const { return first_free; }

	std::string & operator[](std::size_t n)
	{ return elements[n]; }

private:
	static std::allocator alloc;	// allocates the elements
	std::string *elements;	// pointer to the first element in the array
	std::string *first_free;// pointer to the first free element in the array
	std::string *cap;		// pointer to one past the end of the array
	
	// utility functions:
	// used by members that add elements to the Str_vec
	void chk_n_alloc()
		{ if (size() == capacity()) reallocate(); }
	// used by the copy constructor, assignment operator, and destructor
	std::pair alloc_n_copy
		(const std::string *, const std::string *);
	void free();			// destroy the elements and free the space
	void reallocate();		// get more space and copy the existing elements
};

#endif

/***********************************************
 * IDE:  VS2010
 * FILE: Str_vec.cpp
 ***********************************************/
#include 
using std::string;

#include 	// for uninitialized_copy
using std::allocator; using std::uninitialized_copy;

#include 	// for move
using std::pair; 

#include "Str_vec.h"

// utility function
void Str_vec::push_back(const string &s)
{
	chk_n_alloc();	// ensure that there is room for another element
	// construct a copy of s in the element to which first_free points
	alloc.construct(first_free++, s);
}

// the first member of the returned pair points to the
// start of the allocated memory;
// the second is pointer positioned one element past the
// last constructed element.
pair 
Str_vec::alloc_n_copy(const string *b, const string *e)
{
	// allocate space to hold as many elements as are in the range
	string *data = alloc.allocate(e - b);
	
	// initialize and return a pair constructed from data and
	// the value returned by uninitialized_copy
	return make_pair(data, uninitialized_copy(b, e, data));
}

Str_vec::Str_vec(const std::string *b, const std::string *e)
{
	// copy alloc_n_copy to allocate exactly as many elements as in the range
	pair newdata = alloc_n_copy(b, e);
	elements = newdata.first;
	first_free = cap = newdata.second;
}

// destroy the element, and then deallocate the space 
// that this Str_vec itself allocated
void Str_vec::free()
{
	// may not pass deallocate a 0 pointer; if element is 0,
	// there's no work to do
	if (elements)
	{
		for (string *p = first_free; p != elements; /* empyt */)
		{
			alloc.destroy(--p);
		}
		alloc.deallocate(elements, cap - elements);
	}
}

// copy constructor
Str_vec::Str_vec(const Str_vec &s)
{
	// call alloc_n_copy to allocate exactly as many elements as in s
	pair newdata = alloc_n_copy(s.begin(), s.end());
	elements = newdata.first;
	first_free = cap = newdata.second;
}

// copy-assignment operator
Str_vec &Str_vec::operator=(const Str_vec &rhs)
{
	// call alloc_n_copy to allocate exactly as many elements in rhs
	pair data = alloc_n_copy(rhs.begin(), rhs.end());
	free();
	elements = data.first;
	first_free = cap = data.second;
	return *this;
}

void Str_vec::reallocate()
{
	// we'll allocate space for twice as many elements as the current size
	size_t newcapacity = size() ? 2 * size() : 1;
	// allocate new memory
	string *newdata = alloc.allocate(newcapacity);
	// move the data from the old memory to the new
	string *dest = newdata;	// points to the next free position in the new array
	string *elem = elements;// points to the next element in the old array
	for (size_t i = 0; i != size(); ++i)
	{
		alloc.construct(dest++, std::move(*elem++));
	}
	free();		// free the old space once we've moved the elements
	// update our data structure to point to the new elements
	elements = newdata;
	first_free = dest;
	cap = elements + newcapacity;
}
/***********************************************
 * IDE:  VS2010
 * FILE: use_Str_vec.cpp
 ***********************************************/
#include 
using std::string;

#include 
using std::begin; using std::end;

#include 
using std::allocator;

#include 
using std::cin; using std::cout; using std::endl;

#include "Str_vec.h"

void print(const Str_vec &svec)
{
	for (string *iter = svec.begin(); iter != svec.end(); ++iter)
	{
		cout << *iter << " ";
	}
	cout << endl;
}


allocator Str_vec::alloc;

int main(void)
{
	string temp[] = {"Alice", "two", "three"};
	Str_vec sv(begin(temp), end(temp));

	if (!sv[0].empty())
	{
		sv[0] = "one";
	}
	print(sv);		// print "None" "two" "three"

	cout << "1. copy " << sv.size() << endl;
	Str_vec svec = sv;
	print(svec);

	cout << "2. push_back " << "four" << " five" << endl;
	string s = "four";
	sv.push_back(s);
	sv.push_back("five");
	print(sv);

	cout << "3. assignment operator " << sv.size() << endl;
	Str_vec vec;	// empty Str_vec
	vec = sv;
	print(vec);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值