2015-03-05 2 views
-2

Я прошел через некоторые потоки в той же теме, но они действительно продвинуты как набор и все. Для кого-то, просто найдя его шаги на C++, какой был бы лучший способ справиться с этим?Предоставление размера (const) массива-члена в качестве аргумента конструктора RELOADED

Следующий код дает мне ошибку:

class AStack { 
    public: 
     AStack(int size) : max_Size(size) { 
     } 
     void push(int); 
     int pop(); 
     int top(); 
     bool isEmpty(); 
     void Flush(); 

    private: 
     const int max_Size; 
     int a[max_Size]; 
     int index = -1; // Index of the top most element 
}; 
+1

Исправьте основные опечатки (например, 'AStack' против' Astack') и не заставляйте нас угадывать, какие ошибки вы получаете. –

+0

О, боже мой ... действительно испортил это, не так ли?Кроме того, если max_Size является статическим элементом данных, то нет смысла инициализировать его с помощью конструктора. Итак, теперь он стал нестационарным. –

+0

Он должен быть статичным и инициализироваться в классе, который можно использовать в качестве постоянного выражения для размера массива. Если вы хотите указать размер во время выполнения, вы не можете использовать простой массив; используйте динамический массив типа 'std :: vector'. –

ответ

3

У вас есть 3 варианта здесь.

  1. Превратите класс в шаблон, и параметр depth станет аргументом шаблона. Затем он является постоянным, и вы можете создать массив с соответствующим размером.
  2. Используйте вектор std :: для вашего внутреннего массива и используйте метод resize().
  3. Сделайте max_depth a static const uint32_t max_depth = 42; (Инициализируйте в классе), а затем вы можете использовать этот max_depth, также как размер для массива a.

Решение 1 выглядит то вроде этого:

template <size_t max_depth> 
class AStack 
{ 
    // ... 
    int a[max_depth]; 
}; 

Решение 2 будет выглядеть следующим образом:

#include <vector> 
class AStack 
{ 
public: 
    AStack(size_t max_depth) 
    { 
      a.resize(max_depth); 
      // ... 
    } 
    // ... 
    std::vector<int> a; 
    // ... 
}; 

Решение 3 будет выглядеть так:

class AStack 
{ 
    static const int max_depth = 42; 
    int a[max_depth]; 
    // ... 
}; 

Фиксированный размер c-массивы могут быть объявлены только с помощью выражения с постоянным размером массива.
Конструктор воздействует на нестатические элементы класса. Статические константные члены класса инициализируются «жестко запрограммированными».

Поэтому, если вы хотите разрешить пользователям этого класса использовать его с различными размерами стека, вам потребуется вариант 1 или вариант 2. Если вы хотите жестко закодировать размер стека в классе, используйте опцию 3. Вариант 2 также можно выполнить «вручную» с использованием оператора new() или new() вместо std :: vector. Но тогда у вас есть гораздо больше, чтобы набирать, проверять, и у вас, скорее всего, будут ошибки, которые не будут впечатлять вашего инструктора;)

+0

Хммм ... спасибо. Я понимаю причину использования векторов, но нас этому не научили, и я хотел произвести впечатление на моего инструктора, сделав это с помощью массивов. догадаться, что невозможно инициализировать массив таким образом? –

+0

Нет, только более опасно, так как вам придется использовать операции динамической памяти для достижения того же эффекта, что и std :: vector. – BitTickler

+0

Проще говоря, вы не можете определить размер регулярного c-массива в любом «определенном времени выполнения». Размер должен быть постоянным, поскольку он является частью определения класса sizeof (AStack), и этот размер не может измениться во время выполнения. – BitTickler

0

Очевидно, что это учебное упражнение, поэтому прямое решение с std::vector не работает для тебя. Это означает, что вам нужно использовать указатели и динамическое распределение.

Объявите массив как указатель вместо:

int * a; 

В конструкторе выделить соответствующий массив размера:

AStack(int size) : max_Size(size), a(new int[size]) 

И всякий раз, когда вы выделяете память, вам нужно освободить его, когда вы» сделайте с ним. В этом случае, в деструкторе.

~AStack() { 
    delete [] a; 
} 

Поскольку деструктор больше не тривиален, то rule of three предполагает, что вам нужен конструктор копирования и оператор присваивания тоже. Я оставлю эту часть тебе.

+0

Я хочу стать гением, как вы в один прекрасный день. Большое вам спасибо, сэр. Уважение. –

+0

Хм ... с помощью оператора присваивания, вы имеете в виду перегрузку оператора '='? –

+0

@TrentBoult да, это именно то, что я имею в виду. И спасибо! –

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