Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Связывание файлов с шаблонным классом |
Автор: Kuvaldis 17.6.2006, 11:49 |
Буду рад любой помощи. Проблема в следующем. Если 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. что-то не получается пользоваться тегами, чтобы код симпатичный был, мож кто скажет как? |
Автор: LPBOY 17.6.2006, 12:30 | ||||
Шаблоны вместе со всей своей реализацией должны находиться в *.h файле. Никаких переносов реализации в *.cpp, как с обычными классами/функциями, не допускается. Есть правда ключевое слово export, которое позволяет это делать, но его поддерживают только компиляторы comeau (и новые версии intel compiler кажется). Или для каждой специализации шаблона, в хедере можешь написать
если память не изменяет.
Щелкаешь по кнопке "Код", появляются теги [сode=cpp] [/сode] между ними пишешь код. ![]() |
Автор: Kuvaldis 17.6.2006, 12:34 |
По-моему суть header-файла тогда теряется: предоставить интерейс класса (шаблона) Хотя с помещением реализации из cpp в header прогамма работает, но.. выдает интересный warning [C++ Warning] Array.cpp(4): W8058 Cannot create pre-compiled header: header incomplete Хотелось бы для данной программы все таки 3 файла ![]() Добавлено @ 12:37 Sorry LPBOY, присал сообщение как раз в тот момент когда ты мне отписал (ответ твой понял) Спасибо. Хотя warning все равно интересный (см. выше) |
Автор: Kuvaldis 17.6.2006, 13:20 | ||||
Хорошо, описываем реализацию в header-файле, но не в теле класса, а отдельно: теперь Builder компилирует, а visual 6 выдает ошибку: header:
MAIN
Ошибка следующая: 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>'" Или я не прав? |
Автор: LPBOY 17.6.2006, 13:37 | ||
У меня на VC7.1 скомпилировалась, правда не слинковалась. ![]() После добавления угловых скобочек friend ostream & operator << <> (ostream & output, Array<T> & theArray); работает, выдает
|
Автор: DeadSoul 17.6.2006, 14:05 | ||||
Читай книгу Вандервуда по шаблонам. У шаблона есть принципиальные отличия от класса
Тебе по-русски сказали "Не могу получить доступ к приватной переменной" |
Автор: LPBOY 17.6.2006, 14:09 | ||
Так он там к функции русским по белому приписал "friend". |
Автор: Kuvaldis 17.6.2006, 14:35 |
Выводы: 1) компилятор VC 6 немного глючный (1 раз - случайность, 2 - тенденция, это уже третий - и последний : закономерность) 2) реализация шаблона должна быть в том же header-файле 2) LPBOY, будь у меня 100 постов, увеличил бы тебе репутацию, а так, огромнейшее спасибо (компилируется в visual dtudio 2005 тоже) |
Автор: Earnest 19.6.2006, 08:40 |
Не глючный, а не совсем соответствует стандарту, в частности, в том, что касается шаблонов. Это так. LPBOY, + за Kuvaldis. |