带有 for-each 支持的自定义列表 C++
custom list with for-each support c++
首先我要为我的英语道歉。我的问题很奇怪,因为我正在尝试编写自己的 ArrayList,其外观和工作方式与 Java 中的 List 类似,我知道这就像重新发明一个轮子,但我这样做是为了好玩并更好地理解它是如何工作的。所以像 "use STL"、"use vector"、"use something else but don't create own list" 这样的每个答案都没有帮助。
所以从一开始,我就有自己的 ArrayList 模板和一些对我很重要的方法。我的 ArrayList 用作数组,我只使用可用 space 的一部分,如果我需要更多 space 我创建新的更大的数组并复制所有旧元素(我相信它在 Java ArrayList,如果我错了请告诉我)。在数组中我只存储指针。它是保存和删除已知对象的好模板,如果我只需要读取存储的数据,但是当我尝试写循环读取、检查和删除列表中的指定元素时,真正的问题出现了。我不能使用标准 for(int i=0;i
- Supporting "for each" on custom const native C++ container class
- supporting for each loop in classes
- C++ for each in on custom collections
- How to make the for each loop function in C++ work with a custom class
- Creating my own Iterators
- http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html
那么谁能解释一下我应该在模板中写些什么来支持每个功能。在许多例子中出现了 begin() 和 end() 函数,但没有人解释为什么这个名字,什么是 return 类型和为什么,以及这个方法应该是什么 return。这是我的模板代码,如果有问题,请告诉我。我将在我的其他应用程序中使用此代码,因为对我而言,此实现比向量更直观(我肯定太长时间使用 Java :))
template <class T> class ArrayList {
public:
ArrayList() {
array = new T*[1000];
arraySize = 1000;
n = 0;
};
void add(T &arg) { //add new element at end
if (n == arraySize) {
increase();
}
array[n] = &arg;
n++;
};
void addAt(T &arg, unsigned int pos) { //add new element at specific position and override
if (pos >= 0 && pos <= n) {
if (pos == n) {
add(arg);
}
else {
array[pos] = &arg;
}
}
else {
throw "IndexOutOfBoundException";
}
};
void addAfter(T &arg, unsigned int pos) { //add new element between specific posittion and next element
pos++;
if (pos >= 0 && pos <= n) {
if (n == arraySize) {
increase();
}
for (unsigned int i = n; i > pos; i--) {
array[i] = array[i - 1];
}
array[pos] = &arg;
n++;
}
else {
throw "IndexOutOfBoundException";
}
};
void addList(ArrayList &list) { //add 'list' at the end
if (list.n > 0) {
while (list.n + n > arraySize) {
increase();
}
for (int i = 0; i < list.n; i++) {
array[n] = list.array[i];
n++;
}
}
};
void addListAfter(ArrayList &list, unsigned int pos) { //put 'list' inside list, start from 'pos'
pos++;
if (list.n > 0 && pos >= 0 && pos < n) {
while (list.n + n > arraySize) {
increase();
}
int m = n - 1;
while (m >= pos && m >= 0) {
array[m + list.n] = array[m];
m--;
}
for (int i = 0; i < list.n; i++) {
array[pos + i] = list.array[i];
}
n += list.n;
}
else {
throw "IndexOutOfBoundException";
}
};
void addListAfter(ArrayList &list, T &arg) { //put 'list' inside list, start after T, if T not exist 'list' will be added at the end
addListAfter(list, getIndex(arg));
};
void remove(T &arg, bool all) { //remove selected element if all=true remove all instance of object otherwise remove only first
if (all) {
int copies = 0;
for (int index = 0; index < n; index++) {
if (array[index] == &arg) {
copies++;
}
else if (copies != 0) {
array[index - copies] = array[index];
}
}
n -= copies;
if (copies == 0) {
throw "ArgumentNotFoundException";
}
while (arraySize - n >= 1000) {
decrease();
}
}
else {
remove(getIndex(arg));
}
};
void remove(unsigned int pos) { //remove element from specific position
if (pos >= 0 && pos < n) {
for (int i = pos; i < n - 1; i++) {
array[i] = array[i + 1];
}
n--;
if (arraySize - n >= 1000) {
decrease();
}
}
else {
throw "IndexOutOfBoundException";
}
};
void removeCopy(T &arg) { //leaves only one instance of an object and remove all other
int copies = -1;
for (int index = 0; index < n; index++) {
if (array[index] == &arg) {
copies++;
}
else if (copies > 0) {
array[index - copies] = array[index];
}
}
n -= copies;
if (copies == -1) {
n--;
throw "ArgumentNotFoundException";
}
while (arraySize - n >= 1000) {
decrease();
}
};
void repair() { //leaves only single instance of each object
for (int i = 0; i < n; i++) {
removeCopy(*array[i]);
}
};
void clear() { //remove all object from list
for (int i = 0; i < n; i++) {
array[i] = NULL;
}
n = 0;
};
T* get(unsigned int pos) { //return object on selected position
if (pos >= 0 && pos < n) {
return array[pos];
}
else {
throw "IndexOutOfBoundException";
}
};
unsigned int getIndex(T &arg) { //return position of selected object
unsigned int index = 0;
while (&arg != array[index] && index < n) {
index++;
}
if (index == n) {
throw "ArgumentNotFoundException";
}
return index;
};
ArrayList getSubList(unsigned int first, unsigned int last, bool deepCopy) { //return new list contains 'deep copy'/'copy reference' of all elements from (include) first to (include) last. If deepCopy=true function return deep copy, otherwise return copy of reference.
if (first < last&&first >= 0 && last < n) {
ArrayList<T> ret;
for (unsigned int i = first; i <= last; i++) {
if (deepCopy) {
ret.add(*new T(*array[i]));
}
else {
ret.add(*array[i]);
}
}
return ret;
}
throw "IndexOutOfBoundException";
};
unsigned int size() { //return size of list
return n;
};
bool isEmpty() {
return n == 0;
};
T *begin() {
return &*array[0];
}
T *end() {
return &*array[n];
}
private:
unsigned int arraySize; //actual size of array
unsigned int n; //number of elements in array
T** array;
void increase() { //increase size of array about 1000
if (arraySize + 1000 <= LONG_MAX) {
T** newArray = new T*[arraySize + 1000];
for (unsigned int i = 0; i < arraySize; i++) {
newArray[i] = array[i];
}
delete[] array;
array = newArray;
arraySize += 1000;
}
else {
throw "ArraySizeOutOfBoundException";
}
};
void decrease() { //decrease size of array about 1000
if (arraySize - 1000 > 0) {
arraySize -= 1000;
T** newArray = new T*[arraySize];
for (unsigned int i = 0; i < arraySize; i++) {
newArray[i] = array[i];
}
delete[] array;
array = newArray;
}
else {
throw "ArraySizeOutOfBoundException";
}
};
};
您发布的一些答案给出了很好的解释。 begin
和 end
return 迭代器进入容器,其中 begin
指的是第一个元素,end
指的是最后一个元素之后的一个项目的位置。至于名称,它们似乎很直观。我相信这个迭代器设计被选为对指针的抽象,它具有最小的运行时成本。
我确定您在 link 的答案中看到了这个 link,但您应该参考 range-based for-loops 上的此页面。
无论如何,您似乎对数组元素与指向元素的迭代器感到困惑。有:
T **begin() {
return &array[0];
}
T **end() {
return &array[n];
}
您的程序将适用于 ranged-for。您的元素类型是 T*
,而不是 T
。
首先我要为我的英语道歉。我的问题很奇怪,因为我正在尝试编写自己的 ArrayList,其外观和工作方式与 Java 中的 List 类似,我知道这就像重新发明一个轮子,但我这样做是为了好玩并更好地理解它是如何工作的。所以像 "use STL"、"use vector"、"use something else but don't create own list" 这样的每个答案都没有帮助。 所以从一开始,我就有自己的 ArrayList 模板和一些对我很重要的方法。我的 ArrayList 用作数组,我只使用可用 space 的一部分,如果我需要更多 space 我创建新的更大的数组并复制所有旧元素(我相信它在 Java ArrayList,如果我错了请告诉我)。在数组中我只存储指针。它是保存和删除已知对象的好模板,如果我只需要读取存储的数据,但是当我尝试写循环读取、检查和删除列表中的指定元素时,真正的问题出现了。我不能使用标准 for(int i=0;i
- Supporting "for each" on custom const native C++ container class
- supporting for each loop in classes
- C++ for each in on custom collections
- How to make the for each loop function in C++ work with a custom class
- Creating my own Iterators
- http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html
那么谁能解释一下我应该在模板中写些什么来支持每个功能。在许多例子中出现了 begin() 和 end() 函数,但没有人解释为什么这个名字,什么是 return 类型和为什么,以及这个方法应该是什么 return。这是我的模板代码,如果有问题,请告诉我。我将在我的其他应用程序中使用此代码,因为对我而言,此实现比向量更直观(我肯定太长时间使用 Java :))
template <class T> class ArrayList {
public:
ArrayList() {
array = new T*[1000];
arraySize = 1000;
n = 0;
};
void add(T &arg) { //add new element at end
if (n == arraySize) {
increase();
}
array[n] = &arg;
n++;
};
void addAt(T &arg, unsigned int pos) { //add new element at specific position and override
if (pos >= 0 && pos <= n) {
if (pos == n) {
add(arg);
}
else {
array[pos] = &arg;
}
}
else {
throw "IndexOutOfBoundException";
}
};
void addAfter(T &arg, unsigned int pos) { //add new element between specific posittion and next element
pos++;
if (pos >= 0 && pos <= n) {
if (n == arraySize) {
increase();
}
for (unsigned int i = n; i > pos; i--) {
array[i] = array[i - 1];
}
array[pos] = &arg;
n++;
}
else {
throw "IndexOutOfBoundException";
}
};
void addList(ArrayList &list) { //add 'list' at the end
if (list.n > 0) {
while (list.n + n > arraySize) {
increase();
}
for (int i = 0; i < list.n; i++) {
array[n] = list.array[i];
n++;
}
}
};
void addListAfter(ArrayList &list, unsigned int pos) { //put 'list' inside list, start from 'pos'
pos++;
if (list.n > 0 && pos >= 0 && pos < n) {
while (list.n + n > arraySize) {
increase();
}
int m = n - 1;
while (m >= pos && m >= 0) {
array[m + list.n] = array[m];
m--;
}
for (int i = 0; i < list.n; i++) {
array[pos + i] = list.array[i];
}
n += list.n;
}
else {
throw "IndexOutOfBoundException";
}
};
void addListAfter(ArrayList &list, T &arg) { //put 'list' inside list, start after T, if T not exist 'list' will be added at the end
addListAfter(list, getIndex(arg));
};
void remove(T &arg, bool all) { //remove selected element if all=true remove all instance of object otherwise remove only first
if (all) {
int copies = 0;
for (int index = 0; index < n; index++) {
if (array[index] == &arg) {
copies++;
}
else if (copies != 0) {
array[index - copies] = array[index];
}
}
n -= copies;
if (copies == 0) {
throw "ArgumentNotFoundException";
}
while (arraySize - n >= 1000) {
decrease();
}
}
else {
remove(getIndex(arg));
}
};
void remove(unsigned int pos) { //remove element from specific position
if (pos >= 0 && pos < n) {
for (int i = pos; i < n - 1; i++) {
array[i] = array[i + 1];
}
n--;
if (arraySize - n >= 1000) {
decrease();
}
}
else {
throw "IndexOutOfBoundException";
}
};
void removeCopy(T &arg) { //leaves only one instance of an object and remove all other
int copies = -1;
for (int index = 0; index < n; index++) {
if (array[index] == &arg) {
copies++;
}
else if (copies > 0) {
array[index - copies] = array[index];
}
}
n -= copies;
if (copies == -1) {
n--;
throw "ArgumentNotFoundException";
}
while (arraySize - n >= 1000) {
decrease();
}
};
void repair() { //leaves only single instance of each object
for (int i = 0; i < n; i++) {
removeCopy(*array[i]);
}
};
void clear() { //remove all object from list
for (int i = 0; i < n; i++) {
array[i] = NULL;
}
n = 0;
};
T* get(unsigned int pos) { //return object on selected position
if (pos >= 0 && pos < n) {
return array[pos];
}
else {
throw "IndexOutOfBoundException";
}
};
unsigned int getIndex(T &arg) { //return position of selected object
unsigned int index = 0;
while (&arg != array[index] && index < n) {
index++;
}
if (index == n) {
throw "ArgumentNotFoundException";
}
return index;
};
ArrayList getSubList(unsigned int first, unsigned int last, bool deepCopy) { //return new list contains 'deep copy'/'copy reference' of all elements from (include) first to (include) last. If deepCopy=true function return deep copy, otherwise return copy of reference.
if (first < last&&first >= 0 && last < n) {
ArrayList<T> ret;
for (unsigned int i = first; i <= last; i++) {
if (deepCopy) {
ret.add(*new T(*array[i]));
}
else {
ret.add(*array[i]);
}
}
return ret;
}
throw "IndexOutOfBoundException";
};
unsigned int size() { //return size of list
return n;
};
bool isEmpty() {
return n == 0;
};
T *begin() {
return &*array[0];
}
T *end() {
return &*array[n];
}
private:
unsigned int arraySize; //actual size of array
unsigned int n; //number of elements in array
T** array;
void increase() { //increase size of array about 1000
if (arraySize + 1000 <= LONG_MAX) {
T** newArray = new T*[arraySize + 1000];
for (unsigned int i = 0; i < arraySize; i++) {
newArray[i] = array[i];
}
delete[] array;
array = newArray;
arraySize += 1000;
}
else {
throw "ArraySizeOutOfBoundException";
}
};
void decrease() { //decrease size of array about 1000
if (arraySize - 1000 > 0) {
arraySize -= 1000;
T** newArray = new T*[arraySize];
for (unsigned int i = 0; i < arraySize; i++) {
newArray[i] = array[i];
}
delete[] array;
array = newArray;
}
else {
throw "ArraySizeOutOfBoundException";
}
};
};
您发布的一些答案给出了很好的解释。 begin
和 end
return 迭代器进入容器,其中 begin
指的是第一个元素,end
指的是最后一个元素之后的一个项目的位置。至于名称,它们似乎很直观。我相信这个迭代器设计被选为对指针的抽象,它具有最小的运行时成本。
我确定您在 link 的答案中看到了这个 link,但您应该参考 range-based for-loops 上的此页面。
无论如何,您似乎对数组元素与指向元素的迭代器感到困惑。有:
T **begin() {
return &array[0];
}
T **end() {
return &array[n];
}
您的程序将适用于 ranged-for。您的元素类型是 T*
,而不是 T
。