Здравствуйте, гость ( Вход | Регистрация )
igor_bogomolov | Дата 31.10.2010, 14:09 |
Но почему-то у меня нет кнопки правка сообщений Появится после 20 сообщений. Если я правильно понял, это вы уже не про хедеры, а про форварды в *.cpp файлах? Это я про разделение объявления шаблонного класса и его реализации по .cpp/.h фалам http://www.cppreference.com/wiki/keywords/export (если конечно я правильно идею понял, попробовать, как вы понимаете, это не получится)Цитата Привык я форвары в хедерах юзать вместо инклудов. :-) Аналогично. Если в классе объявленны только ссылки и указатели, не вижу ни какого смысла делать инклуд, только форвард объявление ![]() |
|
Алексей1153 | Дата 31.10.2010, 13:50 |
Привык я форвары в хедерах юзать вместо инклудов. :-) это не должно быть самоцелью. Частенько в этом нет необходимости, но ведёт к затратам времени на разработку плюс учитывание ручного управления памятью. Причины использовать форвард - это кросс-ссылка или большой объём кода. Других причин не вижу )) |
|
daorus | Дата 31.10.2010, 13:47 |
достигается вставкой инклюда в одном месте кода У меня почему-то активное использование форвардов существенно экономит время компиляции. + если зависимость от форварда, то изменение в заголовочном файле не генерит флаг на перекомпиляцию. А вообще это просто вопрос привычки. Привык я форвары в хедерах юзать вместо инклудов. :-)всё объясняется проще: когда мелкософтовский компилер а я на g++ работаю. Про msvc вообще ничего не знаю.Тут ошибка, должно быть template<class, class> class b; Да, конечно. Я слишком увлекся идеей. Но почему-то у меня нет кнопки правка сообщений, поэтому баг так и останется висеть в моем посте. :-(с использованием ключевого слова export Если я правильно понял, это вы уже не про хедеры, а про форварды в *.cpp файлах? т.е. типа такого
Вы это имели ввиду? |
|
igor_bogomolov | Дата 31.10.2010, 13:34 |
с MSVC, то нельзя выносить реализацию шаблонного класса из его объявления (это баг MSVC, несовместимость со стандартами). то есть, в заголовочнике должен быть весь класс так и оставил в заголовочнике весь шаблон При чем здесь MSVC? Разделить реализацию и объявление шаблона можно только с использованием ключевого слова export, которое ни один компилятор так и не реализовал. Поэтому для шаблонов подходит только модель включения, т.е. в одном файле должны быть все объявления и определения шаблона. У Вандевурда & Джосатиса это хорошо описано.template<class, class> b; // шаблонный форвард Тут ошибка, должно быть template<class, class> class b;Кстати, по поводу того зачем нужны форвард объявления хорошо описано в этой книге (ссылка) (см. раздел 2.3) --Добавлено чуть позже-------------------------------------------------------------------------- Этого вообще не понял всё объясняется проще: когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. это и есть баг компилера, его несоответствие стандарту. просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован, либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта. Разберем по частям Цитата когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. совершенно правильно считаетЦитата просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован а как вы собираетесь использовать класс, если в данном листе трансляции ничего про него не известно? Естественно нужно делать инклуд, и шаблоны тут не при чемЦитата либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта какой еще фиктивный объект? Где вы его увидели? Там лишь форвард объявление шаблонного класса, никаких объектов не создается |
|
Алексей1153 | Дата 31.10.2010, 12:52 |
экономия времени будет. По крайней мере в студии это очень заметно ![]() Например, класс A (не шаблон), описанный в хедере, не используется в некоем cpp, но из-за вложенности хедеров попал в начало этого cpp. Компилятор его лишний раз скомпилирует (потому что это только у шаблонов не компилируется неиспользыемое). В случае же разнесения кода по A.h и A.cpp , компиляция пройдёт шустрее, так как компилироваться класс A будет всего один раз. Проверить можно так: пусть класс A целиком сидит в A.cpp Можно написать в любой его функции строчку
Везде, где инклуд A.h используется, предупреждение появится (ровно столько же раз, сколько заинклужено) |
|
Iron Bug | Дата 31.10.2010, 12:08 |
Исторически появились как необходимость кросс-вставки классов. воот. так что кроме ссылок на самого себя и циклических ссылок это, конечно, можно, но нафиг нигде не нужно. ибо всё,что нужно компилеру - это увидеть описание класса до его использования в коде, что, в случае простого использования класса, достигается вставкой инклюда в одном месте кода, как правило в заголовочнике, где он используется. а в обычном случае, без циклических ссылок, предварительные объявления без инклюда, тем более для стандартно или библиотечно определённых шаблонов, ни к чему, кроме ещё одного лишнего прохода при компиляции, не приводят. куда ты его вставишь - дело десятое. если класс сам по себе используется, то компилятор обработает его один раз. так что "экономия" времени компиляции будет только в случае библиотеки, которая оперирует только указателями и никогда не обращается к самому классу. о да. Столкнулся несколько раз, пытался решить, спрашивал советы - так и оставил в заголовочнике весь шаблон. я как-то тоже напоролась на это. это баг мелкософта. об этом написано где-то в MSDN, только мелким-мелким шрифтом на страничке, которую так просто и не найти ![]() Топик начался с того, что для шаблонных классов создание обычной декларации не катит, а как катит я не знал. И тут мне на форуме подсказали супер-мегафичу, которую я домыслил и оказалось, что для шаблонов форвард-декларацией является как бы создание экземлпяра шаблона! + кстати, подсказанный пример можно существенно сократить, выкинув сигнатуры классов в шаблоне KEY, T. Главное - сохранить кол-во классов в шаблоне. всё объясняется проще: когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. это и есть баг компилера, его несоответствие стандарту. просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован, либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта. |
|
daorus | Дата 31.10.2010, 11:55 |
Iron Bug, во-первых, привет земляку. Я тоже из Екатеринбурга. Цитата но в примере никакой форвард-декларации нет Форвард-декларация - это такой способ сэкономить время на компилции. Форвард декларация - это простое сообщение о существовании сигнатуры. А декларация - это подробное разъяснение, что за этой сигнатурой скрывается. Форвард-деклараци - это любая функция или класс, в синтаксисе которых отсутствуют фигурные скобки - это основной признак форвад-декларации. Исторически появились как необходимость кросс-вставки классов.
Ну а сегодня, её юзают тупо для сокращения времени компиляции, если есть возможность обойтись одними указателями на класс или функцию, потому что размер указателя вне зависимости от типа есть константа.
Топик начался с того, что для шаблонных классов создание обычной декларации не катит, а как катит я не знал. И тут мне на форуме подсказали супер-мегафичу, которую я домыслил и оказалось, что для шаблонов форвард-декларацией является как бы создание экземлпяра шаблона! + кстати, подсказанный пример можно существенно сократить, выкинув сигнатуры классов в шаблоне KEY, T. Главное - сохранить кол-во классов в шаблоне.
|
|
Алексей1153 | Дата 31.10.2010, 11:34 |
то есть, в заголовочнике должен быть весь класс и заголовочник должен быть указан до использования где-либо в коде. о да. Столкнулся несколько раз, пытался решить, спрашивал советы - так и оставил в заголовочнике весь шаблон. Но душа то не удовлетворена ))) Изворачивался-таки, разделял шаблон на шаблонную составляющую и обычную. Последняя составляющая обычно гораздо объёмнее шаблонной, так что оно того стОило ![]() |
|
Litkevich Yuriy | Дата 31.10.2010, 11:30 |
когда класс ссылается сам на себя или на потомков не только. Любой другой класс тоже может быть использован. |
|
Iron Bug | Дата 31.10.2010, 11:08 |
Какой синтаксис форвад-декларации для типа хеш, если я хочу в классе хранить на него указатель а где в приведённом коде форвард-декларация-то? форвард-декларацией называется случай, когда класс ссылается сам на себя или на потомков. ну и всё сказанное (насчёт указателей) тогда справедливо. но в примере никакой форвард-декларации нет. обычное использование шаблонного класса. стандартного инклюда должно хватить. главное, если компилить под вендой, с MSVC, то нельзя выносить реализацию шаблонного класса из его объявления (это баг MSVC, несовместимость со стандартами). то есть, в заголовочнике должен быть весь класс и заголовочник должен быть указан до использования где-либо в коде. |
|
Просмотр темы полностью (откроется в новом окне) | |
![]() |
Текстовая версия | Сейчас: 28.4.2025, 18:21 |