C ++を練習するために、バインドされていない配列を作成しました。ただし、popBackメソッドは正しく機能しません。コードを貼り付けるだけですが、それほど多くないことを願っています。コードはgcc(MacPorts gcc47 4.7.1_1)4.7.1でコンパイルされます。助けていただければ幸いです。ありがとう :)
unbound_array.hpp
#ifndef _unbound_array_h_
#define _unbound_array_h_
#include <iostream>
namespace datastructures
{
template <typename T>
class UnboundArray {
private:
int beta;
int alpha;
int w;
int n;
//T data[];
T *data;
auto reallocate(const int size) -> void;
public:
UnboundArray(): beta(2) {
alpha = 4;
w = 1;
n = 0;
data = new T[w];
}
// void pushBack(T& element);
auto pushBack(T element) -> void;
auto popBack() -> T;
auto operator [](const int& b) -> T&;
};
template <typename T>
auto UnboundArray<T>::pushBack(T element) -> void {
if (n == w) {
reallocate(beta * n);
}
data[n] = element;
n++;
}
template <typename T>
auto UnboundArray<T>::popBack() -> T {
n = (n == 0) ? 0 : (n - 1);
if ((alpha * n <= w) && n > 0) {
reallocate(beta * n);
}
return data[n];
}
template <typename T>
auto UnboundArray<T>::operator [](const int& b) -> T&{
return data[b];
}
template <typename T>
auto UnboundArray<T>::reallocate(const int size) -> void {
int idx = n;
w = size;
T *array = new T[w];
for (int i = 0; i < idx; ++i) array[i] = data[i];
delete[] data;
data = array;
std::cout << "Reallocation. #elements: " << (n + 1)
<< " new size of UnboundArray: " << w << std::endl;
}
} // datastructures
#endif
test.cpp
#include <iostream>
#include "unbound_array.hpp"
using namespace datastructures;
int main() {
int num = 25;
std::cout << "Test of datastructures" <<std::endl;
UnboundArray<int> a;
for (int i = 0; i < num; ++i) {
std::cout << "Adding "<< i <<" to UnboundArray." << std::endl;
a.pushBack(i);
}
for (int i = 0; i < num; ++i) {
std::cout << "array[" << i << "] = "<< a[i] << std::endl;
}
for (int i = 0; i < num; ++i) {
std::cout << "Popping " << a.popBack() << std::endl;
}
return 0;
}
出力
(サイズ変更を伴う)追加は正常に機能し、operator[]も機能します。popBackだけが私を悩ませます。
Popping 24
Popping 23
Popping 22
Popping 21
Popping 20
Popping 19
Popping 18
Popping 17
Popping 16
Popping 15
Popping 14
Popping 13
Popping 12
Popping 11
Popping 10
Popping 9
Reallocation. #elements: 9 new size of UnboundArray: 16
Popping 8
Popping 7
Popping 6
Popping 5
Reallocation. #elements: 5 new size of UnboundArray: 8
Popping 3
Popping 3
Reallocation. #elements: 3 new size of UnboundArray: 4
Popping 556531726
Reallocation. #elements: 2 new size of UnboundArray: 2
Popping -268435456
Popping 0
編集
再割り当てでコードを変更しました。
template <typename T>
auto UnboundArray<T>::reallocate(const int size) -> void {
w = size;
T *array = new T[w];
for (int i = 0; i < w; ++i) array[i] = data[i];
delete[] data;
data = array;
std::cout << "Reallocation. #elements: " << (n + 1)
<< " new size of UnboundArray: " << w << std::endl;
}
今は動作します。
EDIT2
reallocate()
beta * n
で2回呼び出すことはできません。popBack()
である必要がありますw / beta
。
popBack()
returnを返すようになりdata[--n]
ました。配列には。が割り当てられていませんmalloc()
。機能はそこにあります、私はいくつかのチェックを追加するつもりです、しかしそれはほとんどそれです。ありがとうございました。
template <typename T, size_t ALPHA, size_t BETA>
auto UnboundArray<T, ALPHA, BETA>::pushBack(T& element) -> void {
if (n == w) {
reallocate(BETA * n);
}
data[n++] = element;
}
template <typename T, size_t ALPHA, size_t BETA>
auto UnboundArray<T, ALPHA, BETA>::popBack() -> T {
if ((ALPHA * n <= w) && n > 0) {
reallocate(w / BETA);
}
T ret = data[--n];
data[n] = 0;
return ret;
}
template <typename T, size_t ALPHA, size_t BETA>
auto UnboundArray<T, ALPHA, BETA>::operator[](const int& b) -> T& {
return data[b];
}
template <typename T, size_t ALPHA, size_t BETA>
auto UnboundArray<T, ALPHA, BETA>::reallocate(const int size) -> void {
w = size;
T* array = (T*) malloc(sizeof(T) * w);
for (int i = 0; i < n; i++) array[i] = data[i];
free(data);
data = array;
std::cout << "Reallocation. #elements: " << n << " new max size of UnboundArray: " << w << std::endl;
}