2013-08-16 4 views
1

В качестве упражнения я пытаюсь создать класс myArray, который действует как упрощенный класс массива. Вот мой заголовок:C++ создать примитивный класс массива

#ifndef myArray_h 
#define myArray_h 

typedef double ARRAY_ELEMENT_TYPE; 

class myArray { 

public: 
//--constructors 
    myArray(int initMax); 
    // post: Allocate memory during pass by value 

    myArray(const myArray & source); 
    // post: Dynamically allocate memory during pass by value 

//--destructor 
    ~myArray(); 
    // post: Memory allocated for my_data is deallocated. 

//--modifier 
    void set(int subscript, ARRAY_ELEMENT_TYPE value); 
    // post: x[subscript] = value when subscript is in range. 
    //  If not, an error message is displayed. 

//--accessor 
    ARRAY_ELEMENT_TYPE sub(int subscript) const; 
    // post: x[subscript] is returned when subscript is in range. 
    //  If not, display an error message and return [0]. 

private: 
ARRAY_ELEMENT_TYPE* my_data; 
int my_capacity; 
}; 
#endif 

Вот моя реализация:

#include "myArray.h" 
#include <iostream> 
#include <cstring> 

using namespace std; 

typedef double ARRAY_ELEMENT_TYPE; 

//--constructors 
myArray::myArray(int initMax) 
{ 
my_capacity = initMax; 
} 

myArray::myArray(const myArray & source) 
{ 
int i; 
my_data = new ARRAY_ELEMENT_TYPE[source.my_capacity]; 

for(i=0; i < my_capacity; i++) 
    my_data[i] = source.sub(i); 
} 

//--destructor 
myArray::~myArray() 
{ 
delete [ ] my_data; 
} 

//--modifier 
void myArray::set(int subscript, ARRAY_ELEMENT_TYPE value) 
{ 
if(subscript > my_capacity - 1) 
{ 
    cout << "**Error: subscript " << subscript << " not in range 0.." << my_capacity-1 << ". The array is unchanged." << endl; 
} 
else 
    my_data[subscript] = value; 
} 

//--accessor 
ARRAY_ELEMENT_TYPE myArray::sub(int subscript) const 
{ 
if(subscript >= my_capacity) 
{ 
    cout << "**Error: subscript " << subscript << " not in range 0.." << my_capacity-1 << ". Returning first element." << endl; 
    cout << my_data[0]; 
} 
else 
{ 
    return my_data[subscript]; 
} 
} 

И я использую это как тест-пилот:

#include <iostream> 
using namespace std; 
typedef double ARRAY_ELEMENT_TYPE; 
#include "myArray.h" 

void show (const myArray & arrayCopy, int n) 
{ 
for(int j = 0; j < n; j++) 
    cout << arrayCopy.sub(j) << endl; 
} 

int main() 
{ 
int n = 6; 
myArray a(6); 
a.set(0, 1.1); 
a.set(1, 2.2); 
a.set(2, 3.3); 
a.set(3, 4.4); 
a.set(4, 5.5); 
a.set(5, 6.6); 
show(a, n); 
cout << a.sub(11) << endl; 
a.set(-1, -1.1); 

return 0; 
} 

Проблема заключается в том, что, когда я запускаю это , Я ничего не получаю, а затем нажмите «Нажать любую клавишу, чтобы продолжить ...». Что случилось?

+1

Не забывайте [Правило трех] (http://stackoverflow.com/questions/4172722). Два из трех не плохо, но вам не хватает оператора копирования. –

ответ

1

Конструктор myArray не выделяет память для my_data. При первом вызове set он пытается записать неинициализированный указатель. Это приводит к неопределенному поведению, но, скорее всего, произойдет сбой.

Вы должны изменить конструктор для

myArray::myArray(int initMax) 
{ 
    my_capacity = initMax; 
    my_data = new ARRAY_ELEMENT_TYPE[my_capacity]; 
} 

Там есть несколько других вопросов с кодом вы могли бы также рассмотреть вопрос о

В «набор», тест

if(subscript > my_capacity - 1) 

должен be

if(subscript < 0 || subscript > my_capacity - 1) 

Или вы можете изменить аргумент subscript на тип unsigned int.

В sub, линия cout << my_data[0]; предположительно должна быть return my_data[0];

+0

Это решило большинство из них. Теперь я получаю предупреждение о том, что не все пути возврата в 'sub' возвращают значение, но я не могу понять, что произойдет за пределами' if (subscript> = my_capacity) 'и' else'. Я получаю сбой при последнем вызове 'a.set (-1, -1.1)', с выходом «1.1-1. # IND» и ошибкой отладки кучи. – spartanhooah

+0

Я обновил свой ответ нотами о том, что вызывает каждую из этих проблем. – simonc

+0

Я пропустил вашу последнюю строку, которая избавилась от проблемы #IND. Спасибо за вашу помощь (так как я еще не могу проголосовать). – spartanhooah

1
myArray::myArray(int initMax) 
{ 
my_capacity = initMax; 
my_data = new ARRAY_ELEMENT_TYPE[my_capacity]; //You missed this 
} 
0

В дополнении к отсутствующему вашему распределению в текущей реализации, вы также динамическое распределение памяти. Простой тип массива не нужно выделять в куче. Коллекция std::array делает именно то, что вы хотите сделать. Я хотел бы попросить вас взглянуть на его реализацию для примера (если это всего лишь академическое упражнение). Если это для производственной базы кода, используйте то, что уже написано и протестировано.

http://en.cppreference.com/w/cpp/container/array

+0

'std :: array' размер статического размера. Пока мы не получаем массивы с динамическим размером и 'std :: dynarray' в следующем году, нам нужно динамическое распределение, если размер неизвестен во время компиляции. (И в этом вопросе говорится, что это упражнение, поэтому «использовать« вектор »тоже не является полезным ответом). –

+0

Я не утверждал, что использую 'std :: array' или' std :: vector' (если только это не для производственной кодовой базы).Я был довольно откровенен, что он должен посмотреть на реализацию 'std :: array', чтобы посмотреть, как это делается. Его текущая реализация создает нереализованный динамически выделенный массив (другими словами, он знает, насколько он велик во время компиляции, но все равно выделяет его на кучу). –

+0

Нет, текущая реализация принимает размер как параметр конструктора времени выполнения, а не параметр шаблона времени компиляции как 'array'. До следующего года вам нужно динамическое распределение, чтобы справиться с этим. (В примере размер является константой, но нет указания, что класс должен быть ограничен значениями времени компиляции). –

Смежные вопросы