一、问题描述:
1、用C++实现一个数组类,类型和大小可设;提供越界检查;支持整体赋值.......
2、为其提供栈接口适配功能,使其能作为std::stack的容器
二、问题分析:
......
三、实现
//Nathan.Yu
//2008-6-13
#ifndef __YARRAY_H__
#define __YARRAY_H__
#include <algorithm>
namespace ylib
{
template <class T, size_t N>
class YArray
{
public:
// 类型定义
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
/*由于内部数据成员以数组形式存放(无指针类型成员),故无需析构函数。
但若该数组中存放的是指针(即是一个指针数组),则需在外面手工delete掉各个元素,
否则就会造成内存泄露*/
//拷贝构造、类类型参数的赋值操作函数都使用编译器生成的默认函数
public:
//默认构造函数:将数组的所有元素初始化为T()默认值,该值也可显示提供
//不用expliict,使YArray<int, 10> c=20;形式的语句也能通过
/*explicit*/ YArray(const T& value = T())
{
for(int i=0; i<N; ++i)
elems[i] = value;
}
//为实现T2不为T的类型的一般构造
template <class T2>
YArray(const YArray<T2,N>& rhs)
{
std::copy(rhs.begin(), rhs.end(), (T*)elems);
}
//为实现T2不为T的类型的一般赋值
template <class T2>
YArray& operator=(const YArray<T2,N>& rhs)
{
std::copy(rhs.begin(), rhs.end(), begin());
return *this;
}
reference operator[](size_t i)
{
CheckIndex(i);
return elems[i];
}
const_reference operator[](size_t i) const
{
CheckIndex(i);
return elems[i];
}
size_t size() const
{
return N;
}
iterator begin()
{
return elems;
}
const_iterator begin() const
{
return elems;
}
iterator end()
{
return elems+N;
}
const_iterator end() const
{
return elems+N;
}
//以某个值填充整个数组
void fillwith(const T& value)
{
std::fill_n(begin(), N, value);
}
// swap 类型必须相同<T, N>
void swap (YArray<T, N>& rhs) {
std::swap_ranges(begin(), end(), rhs.begin());
}
T* c_array()
{
return elems;
}
const T* c_array() const
{
return elems;
}
private:
void CheckIndex(int i) const
{
if(i<0 || i>=N)
throw "ArrayIndexOutOfRange";
}
private:
T elems[N];
};
//为上面的数组实现一个std::stack适用的堆栈适配器
//即为stack实现其所需的基本要素(函数、接口)
template <class T, size_t N>
class YArrayStackAdapter
{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
public:
YArrayStackAdapter():topIndex(0){}
bool empty() const
{
return topIndex == 0;
}
size_t size() const
{
return a.size();
}
T& back()
{
if(topIndex == 0)
throw std::exception("StackEmpty");
return a[topIndex-1];
}
void push_back(const T& value)
{
if(topIndex == N)
throw std::exception("StackOverFlow");
a[topIndex++] = value;
}
void pop_back()
{
if(topIndex == 0)
throw std::exception("StackEmpty");
--topIndex;
}
private:
size_t topIndex;
YArray<T, N> a;
};
}
#endif