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

Поиск:

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


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


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

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



Буду рад любой помощи. Проблема в следующем. Если 1) нижеприведенный код находится в одном файле или 2)  вместо подключения hpp подключаю cpp (что не есть гуд) то все работает.
иначе выдается ошибка линкера (делаю подключение header-файла, как всегда, что всегда (!) до этого работало как на С, так и для простых классов С++)
В книгах, что я нашел по этому поводу написано ,что я прав (хотя как Builder 6, так и VC 6 так не считают)

ЗАГОЛОВОЧНЫЙ ДЛЯ ШАБЛОНА 

//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
const int DefaultSize = 10;
//---------------------------------------------------------------------------
template <class T> class Array;    
template <class T> extern ostream & operator << (ostream & output, 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]; } 
     int GetSize() const { return itsSize; }
     
     friend ostream & operator << <> (ostream & output, Array<T> & theArray);
};
//----------------------------------------------------------------

РЕАЛИЗАЦИЯ ДЛЯ ЗАГОЛОВОЧНОГО ШАБЛОНА 

//---------------------------------------------------------------------------
#include "Array.hpp"
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------
template <class T>
ostream & operator <<  (ostream & output, Array<T> & theArray)
{
   for(int i = 0; i < theArray.itsSize; i++)
      output << "Array[" << i << "] = " << theArray[i] << endl;
   return output;   
}
//---------------------------------------------------------------------------


MAIN

//---------------------------------------------------------------------------
#include <iostream>
#include "Array.hpp"
//  #include "Array.cpp"   // ЕСЛИ подкючить этот файл вместо hpp то все зер гуд
using namespace std;
//---------------------------------------------------------------------------
#pragma argsused
#pragma hdrstop
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    int    i, n;
    Array <int> theArray(3);

    n = theArray.GetSize();
    for(i = 0; i < n; i++)
      theArray[i] = i * 2;
    cout << theArray;
    
    cin >> i;
    return 0;
}
//---------------------------------------------------------------------------

P.S. что-то не получается пользоваться тегами, чтобы код симпатичный был, мож кто скажет как?


 


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


Эксперт
***


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

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



Цитата(Kuvaldis @  17.6.2006,  11:49 Найти цитируемый пост)
P.S. что-то не получается пользоваться тегами, чтобы код симпатичный был, мож кто скажет как?

Нажми на кнопку "Код" и располагай свой ков внутри появившихся тегов.

По сути: ВЕСЬ шаблон, включая РЕАЛИЗАЦИЮ методов должен находится в h-файле 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
LPBOY
Дата 17.6.2006, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

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



Шаблоны вместе со всей своей реализацией должны находиться в *.h файле. Никаких переносов реализации в *.cpp, как с обычными классами/функциями, не допускается.
Есть правда ключевое слово export, которое позволяет это делать, но его поддерживают только компиляторы comeau (и новые версии intel compiler кажется).

Или для каждой специализации шаблона, в хедере можешь написать
Код

template class Array<int>;

если память не изменяет.
Цитата(Kuvaldis @  17.6.2006,  11:49 Найти цитируемый пост)
P.S. что-то не получается пользоваться тегами, чтобы код симпатичный был, мож кто скажет как?

Щелкаешь по кнопке "Код", появляются теги
[сode=cpp]

[/сode]
между ними пишешь код. smile 
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Kuvaldis
Дата 17.6.2006, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



По-моему суть header-файла тогда теряется:  предоставить интерейс класса (шаблона)
Хотя с помещением реализации из cpp в header прогамма работает, но.. выдает интересный warning 
[C++ Warning] Array.cpp(4): W8058 Cannot create pre-compiled header: header incomplete
Хотелось бы для данной программы все таки 3 файла smile

Добавлено @ 12:37 
Sorry LPBOY, присал сообщение как раз в тот момент когда ты мне отписал (ответ твой понял) Спасибо. Хотя warning все равно интересный (см. выше) 


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


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


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

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



Хорошо, описываем реализацию в header-файле, но не в теле класса, а  отдельно: теперь Builder компилирует, а visual 6 выдает ошибку:

header:

Код

//---------------------------------------------------------------------------
#include <iostream>
using namespace std;
//---------------------------------------------------------------------------
const int DefaultSize = 10;
//---------------------------------------------------------------------------
template <class T> class Array;    
template <class T> ostream & operator << (ostream & output, 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);
};
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------


MAIN

Код

//---------------------------------------------------------------------------
#include <iostream>
#include "Array.hpp"
//#include "Array.cpp"
using namespace std;
//---------------------------------------------------------------------------
#pragma hdrstop
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    int    i, n;
    Array <int> theArray(3);

    n = theArray.GetSize();
    for(i = 0; i < n; i++)
      theArray[i] = i * 2;
    cout << theArray;
    
    cin >> i;
    return 0;
}
//---------------------------------------------------------------------------
template <class T>
ostream & operator << (ostream & output, Array<T> & theArray)
{
   for(int i = 0; i < theArray.itsSize; i++)
      output << "Array[" << i << "] = " << theArray[i] << endl;
   return output;   
}
//---------------------------------------------------------------------------


Ошибка следующая: 
Compiling...
MyTemplate.cpp
G:\Learning\Programming\C\Visual\Temp_1\MyTemplate.cpp(26) : error C2248: 'itsSize' : cannot access private member declared in class 'Array<int>'
  
при реализации функции-шаблона, которая является дружественной и , следовательно, ИМЕЕТ доступ к "private member declared in class 'Array<int>'"
Или я не прав?
    


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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

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



У меня на VC7.1 скомпилировалась, правда не слинковалась. smile
После добавления угловых скобочек
friend ostream & operator << <> (ostream & output, Array<T> & theArray);
работает, выдает
Код

Array[0] = 0
Array[1] = 2
Array[2] = 4
 
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
DeadSoul
Дата 17.6.2006, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Kuvaldis @  17.6.2006,  12:34 Найти цитируемый пост)
По-моему суть header-файла тогда теряется:  предоставить интерейс класса (шаблона)

Читай книгу Вандервуда по шаблонам. У шаблона есть принципиальные отличия от класса

Цитата(Kuvaldis @  17.6.2006,  13:20 Найти цитируемый пост)
G:\Learning\Programming\C\Visual\Temp_1\MyTemplate.cpp(26) : error C2248: 'itsSize' : cannot access private member declared in class 'Array<int>'

Тебе по-русски сказали "Не могу получить доступ к приватной переменной" 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
LPBOY
Дата 17.6.2006, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

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



Цитата(DeadSoul @  17.6.2006,  14:05 Найти цитируемый пост)
Тебе по-русски сказали "Не могу получить доступ к приватной переменной" 

Так он там к функции русским по белому приписал "friend".  

Это сообщение отредактировал(а) LPBOY - 17.6.2006, 14:13
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Kuvaldis
Дата 17.6.2006, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Выводы:
1) компилятор VC 6 немного  глючный (1 раз - случайность, 2 - тенденция, это уже третий - и последний : закономерность)

2) реализация шаблона должна быть в том же header-файле 

2) LPBOY, будь у меня 100 постов, увеличил бы тебе репутацию, а так, огромнейшее спасибо
(компилируется в visual dtudio 2005 тоже) 


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


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Цитата(Kuvaldis @  17.6.2006,  15:35 Найти цитируемый пост)
 компилятор VC 6 немного  глючный 

Не глючный, а не совсем соответствует стандарту, в частности, в том, что касается шаблонов. Это так. 
LPBOY, + за Kuvaldis.  


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

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

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

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

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


 




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


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

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