Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Специализированный конструктор шаблона 
V
    Опции темы
Kuvaldis
Дата 17.6.2006, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



Наверное, модератор меня уже не любит. За 2 дня 3 вопрос по шаблонам. Читаю книгу Либерти "С++ за 21 день".
На этот раз, надеюсь в последний, такая проблема. Использование специализированного конструктора класса шаблона.

template <class T>
Array<T>::Array(int size) : itsSize(size)
{
   pType = new T[size];
   for(int i = 0; i < size; i++)
      pType[i] = 0;

 
   в этом месте неявно size раз вызывается конструктор класса Т при создании шаблона
      Но для некоторых классов инициализация происходит на этапе pType = new T[size] (зависит от конструктора 
      класса). Чтобы этот процесс оптимизировать, Либерти приводит такое решение для конкретного класса
  Array<Animal>::Array(int AnimalSize) : itsSize(AnimalSize)
{
   pType = new Animal[AnimalSize];
}

   Ни в Builder 6, ни в visual 6 и 2005 программа не работает. Хотел было плюнуть, но очень хочется разобраться

код

Код

//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
const int DefaultSize = 10;
//---------------------------------------------------------------------------
class Animal;
ostream & operator << (ostream & output, const Animal & theAnimal);
//---------------------------------------------------------------------------
class Animal
{
  protected:
     int itsWeight;
  public:
     // constructors
     Animal() : itsWeight(0) {}
     Animal(int weight) : itsWeight(weight) {}
     ~Animal() {}
     // access methods
     int GetWeight() const { return itsWeight; }
     void SetWeight(int weight) { itsWeight = weight; }    

     friend ostream & operator << (ostream & output, const Animal & theAnimal);
};
//---------------------------------------------------------------------------
template <class T> class Array;
template <class T> ostream & operator << (ostream & output, const Array<T> & theArray);
//---------------------------------------------------------------------------
template <class T>
class Array
{
  private:
     T*  pType;
     int itsSize;
  public:
     // constructors   
     Array(int size = DefaultSize);   
     Array(const Array & rhs);
     ~Array() { delete [] pType; } 
     // operators
     Array & operator = (const Array & theArray);
     T & operator [] (int offset) { return pType[offset]; }
     const T & operator [] (int offset) const { return pType[offset]; } 
     // access methods
     int GetSize() const { return itsSize; }    

     friend ostream & operator << <> (ostream & output, Array<T> & theArray);
};
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    int    i;
    Array <int> theArray;
    Array <Animal> theZoo;
   
    cout << "\nThe Array: \n" << theArray;
    cout << "\nThe Zoo: \n" << theZoo;
    
    cin >> i;
    return 0;
}
//---------------------------------------------------------------------------
ostream & operator << (ostream & output, const Animal & theAnimal)
{
   output << theAnimal.itsWeight;
   return output;
}
//---------------------------------------------------------------------------
template <class T>
ostream & operator << (ostream & output, const Array<T> & theArray)
{
   for(int i = 0; i < theArray.itsSize; i++)
      output << "Array[" << i << "] = " << theArray[i] << endl;
   return output;   
}
//---------------------------------------------------------------------------

template <class T>
Array<T>::Array(const Array & rhs)
{
   itsSize = rhs.itsSize;
   pType = new T[itsSize];
    for(int i = 0; i < itsSize; i++)
       pType[i] = rhs[i];
}
//---------------------------------------------------------------------------
template <class T>
Array<T> & Array<T>::operator = (const Array & theArray)
{
   if(this == &theArray)
     return *this;
   itsSize = rhs.itsSize;
   delete [] pType;
   pType = new T[itsSize];
   for(int i = 0; i < itsSize; i++)
       pType[i] = theArray[i];
   return *this;
}
//---------------------------------------------------------------------------
template <class T>
Array<T>::Array(int size) : itsSize(size)
{
   pType = new T[size];
   for(int i = 0; i < size; i++)
      pType[i] = 0;

/* в этом месте неявно size раз вызывается конструктор класса Animal при создании шаблона  из 
  его объектов, для этого, следуя главе специализированные функции шаблона книги "С++ за 21 день"
  используем нижеприведенный конструктор, но.. где ошибка?
  */
}
//---------------------------------------------------------------------------

// !!!!!!!!!!!!!!!!!!! problem HERE

Array<Animal>::Array(int AnimalSize) : itsSize(AnimalSize)
{
   pType = new Animal[AnimalSize];
}
//---------------------------------------------------------------------------

 


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Daevaorn
Дата 17.6.2006, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Kuvaldis
Код

template<> //!!!!!!
Array<Animal>::Array(int AnimalSize) : itsSize(AnimalSize)
{
    pType = new Animal[AnimalSize];
}

Данная специализация должна быть до main 
PM MAIL WWW   Вверх
Kuvaldis
Дата 18.6.2006, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



1. Daevaorn, спасибо за ответ. Наберу 100 постов, добавлю тебе репутацию.
2. Получается, что если у меня шаблон описан в отдельном header-файле, а класс Animal в головном cpp, то специализацию придется описывать в головном cpp? 
 


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Athlon
Дата 18.6.2006, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 15.1.2006
Где: Украина:: Запорож ье

Репутация: нет
Всего: нет



Я что-то не пойму, зачем в конструктор шаблона зашивать инициализацию, более логично сделать для этого отдельную фукцию примерно так:
Код

template <class T>    
Array<T>::Array(int size) : itsSize(size)    
{
    pType = new T[size];
}

template <class T>    
void Array<T>::init(T init_value)    
{
    for(int i = 0; i < itsSize; i++)    
        pType[i] = init_value;    
}

При этом в конструкторе шаблона вызывается конструктор класса T без параметров, а в функции init инициализируется конкретным значением, или в данном примере речь идет не о том? 
PM MAIL ICQ   Вверх
Kuvaldis
Дата 18.6.2006, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



Athlon, проблема в том, что если у нас создается  шаблонный класс Array, по умолчанию инициализирующийся нулями. Это происходит в цикле. Но для текоторых классов параметров (например, для Animal, данный цикл излишний, так как ницициализация нужная происходит во время создания массива в памяти (через конструктор класса Animal) 

pType = new T[size];

а в цикле идет pType = 0. Это равносильно pType = (T) 0;
Но что значит Animal = 0?  itsWeight = 0; Что делается до этого конструктором.
Именно для оптимизации данной ситуации и нужен спец. конструктор (извини за сумбурный ответ) 


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Athlon
Дата 18.6.2006, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 15.1.2006
Где: Украина:: Запорож ье

Репутация: нет
Всего: нет



Дык я о том и говорю - пусть в конструкторе шаблона вызывается конструктор без аргументов класса T (Animal), а если нужно инициализировать весь массив конкретным значением, то делать это нужно отдельной функой, например init (см. предидущий пост). А для того чтобы init нормально работала, нужно чтобы у внутренего класса (T или Animal) был перегружен оператор присваивания(если генерируемый компилятором не годится).
Т.е я хочу сказать, что шаблон должен быть максимально универсальным, а если его нужно подстраивать под каждый класс, то зачем такой шаблон нужен? Надеюсь понятна моя точка зрения  smile  
PM MAIL ICQ   Вверх
MAKCim
Дата 18.6.2006, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

а если его нужно подстраивать под каждый класс, то зачем такой шаблон нужен? 

в том то и дело, что шаблон универсален и есть одно исключение для Animal
для чего по-твоему частичная/полная специализация шаблона нужна? 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0955 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.