Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: С++ & Шаблоны классов  (Прочитано 945 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн dronte

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
С++ & Шаблоны классов
« : 06 Октябрь 2013, 01:10:47 »
Код примерно такого содержания:
main.cpp
(Нажмите, чтобы показать/скрыть)
List.h
(Нажмите, чтобы показать/скрыть)
List.cpp
(Нажмите, чтобы показать/скрыть)

ошибки компилятора:
g++ -c List.cpp
g++ -c main.cpp
g++ List.o main.o -o List
main.o: In function `main':
main.cpp:(.text+0x12): undefined reference to `List<double>::List()'
main.cpp:(.text+0x23): undefined reference to `List<double>::~List()'
collect2: ошибка: выполнение ld завершилось с кодом возврата 1
make: *** [List] Ошибка 1

Вопрос, в чем возникла проблема ??
вроде как все есть ...

Оффлайн Peter_I

  • Старожил
  • *
  • Сообщений: 2267
    • Просмотр профиля
Re: С++ & Шаблоны классов
« Ответ #1 : 06 Октябрь 2013, 08:47:32 »
А вы попробуйте для начала включить List.cpp в main, после неё.
При этом сделайте проверку, чтобы List.h не загружался дважды.
Либо командой компилировать оба cpp-модуля.
Либо написать Makefile.

Пётр.
Пётр.

Оффлайн quiet_readonly

  • Участник
  • *
  • Сообщений: 133
    • Просмотр профиля
Re: С++ & Шаблоны классов
« Ответ #2 : 06 Октябрь 2013, 10:15:28 »
Код с шаблонами должен целиком располагаться в заголовке, и это его крупнейший недостаток. Каждый раз, когда шаблонный класс получает параметр, он специализируется, и в этот момент может быть создана реализация шаблонного класса для переданного типа данных (если такая же реализация не была создана ранее) - это называется инстанцирование.

Собственно из-за постоянного инстанцирования и создания множества реализаций для одного и того же шаблонного класса код на C++ компилируется куда медленее, чем код на C или Objective-C. Ну а постоянное инстанцирование возникает из-за того, что директива #include просто включает содержимое заголовочного файла в тот файл, из которого был сделан #include.

Так что перенесите код из List.cpp в List.h либо переименуйте List.cpp в List.inl и уберите его из процесса сборки, а затем включите List.inl в List.h через #include.
« Последнее редактирование: 06 Октябрь 2013, 10:17:25 от quiet_readonly »

Оффлайн dronte

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Re: С++ & Шаблоны классов
« Ответ #3 : 06 Октябрь 2013, 12:28:43 »
Peter_I, компилировалось все как раз таки с помощью мейкфайла, как это можно было заметить по листингу ошибок

Спасибо, quiet_readonly, заработало, как правда тогда быть с тем, что объявление шаблона будет присутствовать целиком во всех файлах где он используется ... хотя читал, что к шаблону можно относиться как к макросу, а тогда проблем быть не должно вроде, ну узнаем.

Оффлайн Астронафтик Чарли

  • Новичок
  • *
  • Сообщений: 3
    • Просмотр профиля
Re: С++ & Шаблоны классов
« Ответ #4 : 06 Октябрь 2013, 13:20:51 »
Интересно  8)
Если хочешь играть симулятор бизнеса, то тебе сюда - http://bizmania.ru/rf/14936

Оффлайн Peter_I

  • Старожил
  • *
  • Сообщений: 2267
    • Просмотр профиля
Re: С++ & Шаблоны классов
« Ответ #5 : 06 Октябрь 2013, 17:32:37 »
Прошу прощения, я спешил и не посмотрел как следует.
Сейчас попробовал скомпилировать это пример как три разных файла,
только List.cpp переименовал в list.cpp, модуль с main скомпилировался,
а list.cpp - нет, сообщения такие:
list.cpp: In destructor ‘List<T>::~List()’:
list.cpp:22:17: error: there are no arguments to ‘GoBegin’ that depend on a template parameter, so a declaration of ‘GoBegin’ must be available [-fpermissive]
         GoBegin();
                 ^
list.cpp:22:17: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
list.cpp:24:26: error: there are no arguments to ‘DelAfter’ that depend on a template parameter, so a declaration of ‘DelAfter’ must be available [-fpermissive]
                 DelAfter();
                          ^
ld: cannot find list: No such file or directory
понятно, что ld не может построить исполнимый файл.

Пётр.
Пётр.

 

Страница сгенерирована за 0.099 секунд. Запросов: 25.