Правила программирования на Си и Си++



         

156. Всегда знайте размер шаблона после его расширения - часть 2


array<int,10>  ten_element_array;

array<int,11>  eleven_element_array;

array<int,12>  twelve_element_array;

array<int,13>  thirteen_element_array;

(то

есть

array<int,10>::operator[](), array<int,11>::operator []() и так далее).

Вопрос состоит в том, как сократить до минимума дублирование кода. Что, если мы уберем размер за пределы шаблона, как на листинге 14? Предыдущие объявления теперь выглядят так:

array<int>  ten_element_array (10);

array<int>  eleven_element_array (11);

array<int>  twelve_element_array (12);

array<int>  thirteen_element_array (13);

Теперь у нас есть только одно определение класса (и один вариант operator[]()) с четырьмя объектами этого класса.

Листинг 14. Шаблон массива (второй проход)

template <class type>

class array

3  {

4     type *array;

5     int size;

public:

7     virtual ~array( void );

8     array( int size = 128 );

9

10    class out_of_bounds {};  //

возбуждается исключение, если

11                             // индекс за пределами массива

12    type &operator[](int index);

13  };

14

15  template <class type>

16  array<type>::array( int sz /*= 128*/ ): size(sz)

17                                  , array( new type[ sz ] )

18  {}

19

20  template <class type>

21  array<type>::~array( void )

22  {

23     delete [] array;

24  }

25

26  template <class type>

27  inline type &array<type>::operator[](int index)

28  {

29     if( 0 <= index && index < size )

30        return array[ index ]

31     throw out_of_bounds;

32  }

Главным недостатком этой второй реализации является то, что вы не можете объявить двухмерный массив. Определение на листинге 13 разрешает следующее:

array< array<int, 10>, 20> ar;

(20-элементный массив из 10-элементных массивов). Определение на листинге 14 устанавливает размер массива, используя конструктор, поэтому лучшее, что вы можете получить, это:




Содержание  Назад  Вперед