我寫了一個未綁定的數組,練習一些C++。但popBack方法無法正常工作。我只是要粘貼我的代碼,我希望它不會太多。代碼是用gcc編譯的(MacPorts gcc47 4.7.1_1)4.7.1。我希望得到一些幫助。謝謝:)未綁定的數組 - 具有奇怪行爲的PopBack
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;
}
輸出
添加(含調整)正常工作,也做運營商[ ]。只是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
被調用兩次,在popBack()
它必須是w/beta
。 popBack()
現在退貨退貨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;
}
你應該注意到,對你的容器使用array-new會強制你的類型是默認的可構造和可賦值的,並且會導致「未使用」元素的不必要的缺省構造。分離內存分配和對象構造(如'std :: vector')是一項重要的設計改進。 – 2012-07-31 14:07:56
我不確定我是否正確,但是使用C++ 11及其新語義,並不是那個問題已經過時(operator =(T &&))。我沒有使用矢量,因爲我知道它可以節省我(大腦)的工作。我想自己做些事情來改善我的數據結構和C++知識。 – jim810 2012-07-31 15:23:16
C++ 11並不神奇。我正在談論C++對象模型的基礎知識。一個動態容器不應該包含比它更多的元素,但是你的版本確實有那些沒有用途的隱藏元素。 properer解決方案是分別管理內存和對象。 – 2012-07-31 15:50:21