|
第2回は配列です int a[3]; としたならば a[0],a[1],a[2] までしかつかえません int a = 5; int b[a]; // ←エラー は許されませんが int a = 5; int *b = new int[a]; // 動的配列の確保 delete[] b; // 動的配列の削除 は許されます
// 配列のアドレスとメモリの関係
#include <iostream>
using namespace std;
int main()
{
int a[10];
int *b = new int[10];
cout << "int型サイズ" << sizeof(int) << endl;
for(int i = 0;i < 10;++i)
{
a[i] = i;
cout << &a[i] << ":" << a[i] << endl;
}
for(int i = 0;i < 10;++i)
{
b[i] = i;
cout << &b[i] << ":" << b[i] << endl;
}
delete[] b;
return 0;
}
また、可変長の配列としてはC++の標準ライブラリであるSTLにvectorクラスと呼ばれるものがあり #ifndef ARRAY_H
#define ARRAY_H
#include <assert.h>
#include <new>
template <class T>
class CArray
{
private:
T *m_pData; // 格納データへのポインタ
int m_length; // 実際に使っている配列の長さ
unsigned long m_capacity; // メモリサイズ
unsigned long m_reserve; // メモリ取得量
public:
int GetLength(); // 配列長取得
unsigned long GetCapacity(); // メモリ使用量取得
CArray();
virtual ~CArray();
void PushBack(T data); // 後ろからつめる
T PopBack(); // 後ろから取り出す
void Reserve(int reserve); // メモリ領域の予約
void Clear(); // 配列開放
CArray(const CArray &obj); // コピーコンストラクタ
CArray &operator=(CArray &obj); // 代入演算子オーバーロード
T operator[](int index); // []のオーバーロード
};
// コンストラクタ
template <class T>
CArray<T>::CArray():m_length(0),m_capacity(0),m_reserve(1),m_pData(NULL)
{
}
// デストラクタ
template <class T>
CArray<T>::~CArray()
{
if(m_pData != NULL)
{
delete[] m_pData;
m_pData = NULL;
}
m_length = 0;
m_capacity = 0;
m_reserve = 1;
}
// 配列長取得
template <class T>
int CArray<T>::GetLength()
{
return m_length;
}
// メモリ使用量取得
template <class T>
unsigned long CArray<T>::GetCapacity()
{
return m_capacity;
}
// 後ろからつめる
template <class T>
void CArray<T>::PushBack(T data)
{
if(m_pData == NULL)
{
try{
m_pData = new T[m_reserve];
}
catch(bad_alloc xa)
{
assert(false);
}
m_pData[m_length] = data; // データ格納
m_length++; // 要素数加算
m_capacity = sizeof(T) * m_reserve; // 確保してあるメモリ領域のサイズ
}
else
{
// メモリ領域を超えていたらメモリ領域作り直し
if(m_length >= (int)m_reserve)
{
m_reserve *= 2; // 倍のメモリ領域を作る
T* tmp;
try{
tmp = new T[m_reserve];
}
catch(bad_alloc xa)
{
assert(false);
}
// 配列コピー
for(int i = 0;i < m_length;++i)
{
tmp[i] = m_pData[i];
}
// 削除
delete[] m_pData;
m_pData = tmp;
m_pData[m_length] = data;
m_length++;
m_capacity = sizeof(T) * m_reserve;
}
// メモリ領域は足りているのでそのまま後ろに追加
else
{
m_pData[m_length] = data;
m_length++;
}
}
}
// 後ろから取り出す
template <class T>
T CArray<T>::PopBack()
{
// 取り出すデータがない
if(m_length <= 0)
return T(); // データのコンストラクタを返す
m_length--;
return m_pData[m_length];
}
template <class T>
void CArray<T>::Reserve(int reserve)
{
// 1未満はありえない
if(reserve < 1)
reserve = 1;
if(reserve > m_reserve)
m_reserve = reserve;
}
// 配列解放
template <class T>
void CArray<T>::Clear()
{
if(m_pData != NULL)
{
delete[] m_pData;
m_pData = NULL;
}
m_length = 0;
m_capacity = 0;
}
// コピーコンストラクタ
template <class T>
CArray<T>::CArray(const CArray &obj):m_length(0),m_capacity(0),m_reserve(1),m_pData(NULL)
{
if(m_pData != NULL)
{
delete[] m_pData;
m_pData = NULL;
}
try{
m_pData = new T[obj.m_reserve];
}
catch(bad_alloc xa)
{
assert(false);
}
m_length = obj.m_length;
m_reserve = obj.m_reserve;
m_capacity = obj.m_capacity;
// 中身のコピー
for(int i = 0;i < m_length;++i)
m_pData[i] = obj.m_pData[i];
}
// 代入演算子オーバーロード
template <class T>
CArray<T> &CArray<T>::operator=(CArray &obj)
{
if(m_pData != NULL)
{
delete[] m_pData;
m_pData = NULL;
}
try{
m_pData = new T[obj.m_reserve];
}
catch(bad_alloc xa)
{
assert(false);
}
m_length = obj.m_length;
m_reserve = obj.m_reserve;
m_capacity = obj.m_capacity;
// 中身のコピー
for(int i = 0;i < m_length;++i)
m_pData[i] = obj.m_pData[i];
return *this;
}
// []のオーバーロード
template <class T>
T CArray<T>::operator[](int index)
{
assert(index >= 0 && index < m_length);
return m_pData[index];
}
#endif
|