Подтвердить что ты не робот

Использование шаблонов в С++

У меня есть домашняя работа, которая просит меня сделать следующее:

Создайте класс шаблонов с именем FlexArray, который предлагает гибкие индексы массивов. Пользователь класса может установить нижний индекс и верхний индекс при объявлении объекта.

Примеры кода пользователя:

FlexArray a (1,5); //Нижний индекс равен 1, а верхний индекс - 5 FlexArray b (-5, 10); // Нижний индекс - -5, а верхний индекс - 10

Предоставьте следующие функции для вашего класса:

  1. конструктор по умолчанию
  2. параметризованный конструктор, в котором пользователь указал нижний индекс и верхний индекс
  3. деструктор
  4. копировать конструктор
  5. оператор присваивания
  6. overloaded [] с аналогичной семантикой [], уже используемой со встроенными массивами.

Ошибки в условиях PRE могут обрабатываться с помощью утверждений или блоков try/catch. Размер массива не изменяется. Подписчики должны находиться в зоне действия.

Книга действительно не помогает создавать шаблоны. Я надеялся, что кто-то предоставит мне какое-то направление по этой проблеме и посмотрит, действительно ли мой код на правильном пути. Я попытался начать эту проблему с очень ограниченного объема книги и различных ресурсов в Интернете и получил:

#ifndef H_templates
#define H_templates

#include <iostream>
using namespace std;

template <typename T>           
class FlexArray
{  public:                  
    FlexArray();            // POST: empty FlexArray
    FlexArray(LI,UI);               // POST: Parameterized Constructor
    ~FlexArray();           // POST: destructor
    CopyArr(Array* sourceArray, Array* destinationArray, size);             // POST: Copies array

    //Overloading the assignment operators to add arrays(?) Unsure if
    // this is what is meant by the original question
    FlexArray operator+
      (const FlexArray& otherFlexArray) const;
      //Overload the operator +
    FlexArray operator-
      (const FlexArray& otherFlexArray) const;
      //Overload the operator -
    FlexArray operator[]
      (const FlexArray& otherFlexArray) const;
      //Overload the operator []

private:
    T FlexArray[size];      // Flex array   
    int size;               // number of items Array
    int LI;                 //Lower Index
    int UI;                 //Upper Index
};

template <typename T>  
FlexArray<T>::FlexArray ()  
// POST: empty FlexArray
{    size = 0;  }

template <typename T>  
FlexArray<T>::~FlexArray()  
// POST: destructor
{    }
template <typename T>  
FlexArray<T>::CopyArr( Array* sourceArray, Array* destinationArray, size)   
//Pre: Takes 3 arguments, the original array, the array to copy too, and, the size of array
// POST: Copies the array
{   
    for(int i=0; i<size; i++){
        sourceArray[i] = destinationArray[i]
    }
}

#endif
4b9b3361

Ответ 1

Вы отправитесь в хорошее начало. Несколько вещей, чтобы указать.

Назначение запрашивает конструктор по умолчанию, НО также указывает, что изменение размера массива не поддерживается. Эти два требования логически конфликтуют - ваше предположение (использовать size=0) кажется логичным, но тогда этот построенный по умолчанию объект всегда будет пустым. Не большая проблема, просто логическое отключение в требованиях.

Парамедированный конструктор, принимающий верхнюю и нижнюю границы. Вы начали с этого:

FlexArray(LI,UI);               // POST: Parameterized Constructor

Однако LI и UI потребуются типы. Поскольку вы должны поддерживать отрицательные индексы, это должен быть подписанный тип, например, int.

Конструктор-копир - это конструктор, который принимает объект того же типа. Вы не объявили об этом. Он должен иметь форму:

FlexArray(const FlexArray&);

Оператором присваивания является оператор = который позволяет это сделать:

FlexArray a, b;
b = a;

Вы не объявили об этом. Он должен иметь форму:

FlexArray& operator=(const FlexArray&);

Реализация будет похожа на экземпляр-конструктор (на самом деле, copy-constructor может быть просто реализован в терминах оператора присваивания).

Перегруженный оператор []. Вы объявили одно из них, но оно не совсем в правильной форме - не принимает соответствующие типы аргументов. Использование будет выглядеть так:

FlexArray arr(-5, 10);

// This is a call to operator[]
arr[3] = value;

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

Теперь о функциональных требованиях. Учитывая верхнюю и нижнюю границы, вам нужно создать массив, который можно индексировать с использованием этих границ. Подумайте о том, что вам нужно знать, чтобы это сделать. Я предлагаю вам знать разницу в верхней и нижней границах (это будет РАЗМЕР вашего массива). Вы должны проверить конструктор, что верхняя граница больше нижней границы, или вы не можете эффективно создать этот массив.

Теперь, чтобы создать массив объектов, вам потребуется динамически выделить для них некоторую память. У вас есть попытка:

T FlexArray[size];      // Flex array

Но у этого есть некоторые проблемы. Во-первых, я не думаю, что вы можете назвать его FlexArray как это столкнется с именем вашего класса. Во-вторых, для этого требуется, чтобы size был константой времени компиляции, которая противоречит нашим требованиям. Таким образом, вам нужно будет динамически распределить внутренний массив объектов T (используя new если вы еще не узнали о интеллектуальных указателях). Не забудьте освободить этот массив объектов в вашем деструкторе.

Теперь функционально, как будет работать []? Требование состоит в том, чтобы выполнять проверку границ, поэтому с учетом индекса, который вы должны знать, если он слишком низкий (вне нижней границы) или слишком высокий (вне верхней границы), и вызывает соответствующую ошибку. Теперь у вас есть динамически выделенный (на основе 0) массив объектов T - с учетом указателя, который указан пользователем, вам нужно найти соответствующий объект для возврата. Подумайте, как это сделать.

Кроме того, вы объявили операторы + и -, хотя в требовании не указывается, что они должны быть там. Я бы предложил взять их. Оператор + предполагает, что размер массива будет изменен (что противоречит требованиям), а - - неоднозначно, что означает вычесть два массива? Обе эти функции могут быть действительными, но для этого назначения нет необходимости.

Больше никаких намеков :)

Ответ 2

Ну, первое, что я заметил с места в карьер, это то, что у вас действительно нет конструктора копий. Если вы CopyArr, что CopyArr квалифицируется, это не так. Синтаксис должен быть в ваших материалах класса, но в основном это конструктор, который принимает const ссылку на класс в качестве единственного параметра.

У вас также нет оператора присваивания (aka: copy assign). Опять же, точный синтаксис должен быть в ваших материалах класса, но имя подпрограммы будет operator=.

Кроме того, у вашего оператора массива мне не кажется, что "аналогичная семантика [] уже используется со встроенными массивами". Встроенный массив возвращает тип элемента (который будет T в вашем случае, нет?), Но ваш возвращает весь тип FlexArray.

Что касается самой разработки шаблона, то здесь я предлагаю, если у вас возникнут проблемы. Начните с разработки всего этого, чтобы работать как простой (не шаблонный) класс с одним простым типом (например: int). Попросите его проверить и проверить, чтобы работать таким образом. Затем преобразуйте его в шаблон. Отслеживание ошибок внутри шаблонов может стать проблемой даже для опытных разработчиков.

Ответ 3

Поскольку другие ответы не вошли в это, есть несколько странных вещей о:

template <typename T>  
FlexArray<T>::CopyArr( Array* sourceArray, Array* destinationArray, size)   
//Pre: Takes 3 arguments, the original array, the array to copy too, and, the size of array
// POST: Copies the array
{    
    for(int i=0; i<size; i++){
        sourceArray[i] = destinationArray[i]
    }
}

Параметру size потребуется тип, а также имя.

Вы сделали его функцией-членом объекта, и все же он вообще не работает с этим объектом. Он работает только с объектами, переданными в параметрах. Вместо этого вы можете использовать эту функцию для одного массива (тот, который нужно скопировать). Позвоните ему assign. Затем вы можете использовать его для реализации своего copy constructor и operator=.

Другой странностью является тип Array. Где это определено?

Ответ 4

Вы хотите динамическое распределение. Самый простой способ сделать это - использовать std::vector.