Использование шаблонов в C ++ - PullRequest
10 голосов
/ 21 октября 2011

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

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

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

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

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

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

Ошибки в условиях PRE могут обрабатываться с помощью операторов assert или блоков 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

Ответы [ 4 ]

6 голосов
/ 21 октября 2011

У тебя хорошее начало.Несколько вещей, на которые нужно указать.

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

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

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

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

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

FlexArray(const FlexArray&);

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

FlexArray a, b;
b = a;

Вы не объявили ни одного из них.Он должен иметь вид:

FlexArray& operator=(const FlexArray&);

Реализация будет аналогична конструктору копирования (фактически конструктор копирования может быть просто реализован в терминах оператора присваивания).

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

FlexArray arr(-5, 10);

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

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

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

Теперь, чтобы фактически построить ваш массив объектов, вам нужно будет динамически распределять некоторую память дляих.Вы можете попробовать это с:

T FlexArray[size];      // Flex array

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

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

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

Нет больше подсказок:)

0 голосов
/ 21 октября 2011

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

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. Где это определено?

0 голосов
/ 21 октября 2011

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

0 голосов
/ 21 октября 2011

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...