![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
daorus |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 20 Регистрация: 30.10.2010 Пользователь №: 2163 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Какой синтаксис форвад-декларации для типа хеш, если я хочу в классе хранить на него указатель
Сообщение отредактировал Litkevich Yuriy - 30.10.2010, 20:27
Причина редактирования: Перенёс, так как относится не к Qt, а к Си++
|
|
|
Алексей1153 |
![]()
Сообщение
#2
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
помести
#include <QHash> #include <QString> в заголовочный файл ну а если поизвращаться всё равно надо, то сделай класс-оболочку, а вот его уже форвардни ![]() Сообщение отредактировал Алексей1153 - 30.10.2010, 20:26 |
|
|
Litkevich Yuriy |
![]()
Сообщение
#3
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Здесь для QString этот номер не пройдёт, т.к. используются не указатели на него.
Вообще forward declaration возможен только в случае применения указателей. Т.к. их размер (в памяти) постоянен |
|
|
kwisp |
![]()
Сообщение
#4
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
интересный вопрос. что на данный вопрос отвечает гугл?
просто так пальцем в небо. template <> class QHash<QString, QString>; не схавает? а вообще конечно - такого рода штуки могут быть непереносимы так что, можно и отказаться от такого рода forward declaration в случае применения указателей. а ссылок? |
|
|
Litkevich Yuriy |
![]()
Сообщение
#5
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Алексей1153 |
![]()
Сообщение
#6
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
ссылка - также, как и указатель. Потому что это одно и тоже для компилятора
![]() |
|
|
igor_bogomolov |
![]()
Сообщение
#7
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Какой синтаксис форвад-декларации для типа хеш, если я хочу в классе хранить на него указатель Да все просто на самом деле
|
|
|
Алексей1153 |
![]()
Сообщение
#8
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
Игорь, сильно сомневаюсь
template <class Key, class T> class QHash; QHash<QString, QString>* dic; а ты проверил, компилится ? Будет ведь переопределение класса QHash из его инклуда Сообщение отредактировал Алексей1153 - 30.10.2010, 21:53 |
|
|
igor_bogomolov |
![]()
Сообщение
#9
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Игорь, сильно сомневаюсь На всякий случай проверил, все работает. Хотя и так знал. В исходниках Qt довольно часто используется такое предварительное объявление шаблонных классов. Будет ведь переопределение класса QHash из его инклуда Вообще этой фразы не понял. Какое еще переопределение?В .h файле нам всего лишь нужно указать тип класса. Никаких уточнений не нужно, так как создается указатель и инстанцирования не происходит. В момент инстанцирования вся информация о параметрах шаблона уже есть |
|
|
Алексей1153 |
![]()
Сообщение
#10
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
igor_bogomolov, всё, дошло до меня
![]() |
|
|
daorus |
![]()
Сообщение
#11
|
Студент ![]() Группа: Участник Сообщений: 20 Регистрация: 30.10.2010 Пользователь №: 2163 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Да все просто на самом деле Круто. Огромное спасибо!==== Раз уж тут чисто по синтаксису вопрос задал. Есть один вопрос, не знаю где спросить. Вот грядет стандарт С+. Там есть лямбды, т.е. функции без сигнатур. А они вообще в кути могут хоть какую-то полезную нагрузку нести или эти лямбды - это просто "с боку бантик"? Сорри за оффтопик, есличо. |
|
|
Litkevich Yuriy |
![]()
Сообщение
#12
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
daorus, лучше следовать правилу:
Одна проблема (вопрос) - одна тема. Так потом проще искать, если приспичит |
|
|
Iron Bug |
![]()
Сообщение
#13
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Какой синтаксис форвад-декларации для типа хеш, если я хочу в классе хранить на него указатель а где в приведённом коде форвард-декларация-то? форвард-декларацией называется случай, когда класс ссылается сам на себя или на потомков. ну и всё сказанное (насчёт указателей) тогда справедливо. но в примере никакой форвард-декларации нет. обычное использование шаблонного класса. стандартного инклюда должно хватить. главное, если компилить под вендой, с MSVC, то нельзя выносить реализацию шаблонного класса из его объявления (это баг MSVC, несовместимость со стандартами). то есть, в заголовочнике должен быть весь класс и заголовочник должен быть указан до использования где-либо в коде. Сообщение отредактировал Iron Bug - 31.10.2010, 11:09 |
|
|
Litkevich Yuriy |
![]()
Сообщение
#14
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Алексей1153 |
![]()
Сообщение
#15
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
то есть, в заголовочнике должен быть весь класс и заголовочник должен быть указан до использования где-либо в коде. о да. Столкнулся несколько раз, пытался решить, спрашивал советы - так и оставил в заголовочнике весь шаблон. Но душа то не удовлетворена ))) Изворачивался-таки, разделял шаблон на шаблонную составляющую и обычную. Последняя составляющая обычно гораздо объёмнее шаблонной, так что оно того стОило ![]() |
|
|
daorus |
![]()
Сообщение
#16
|
Студент ![]() Группа: Участник Сообщений: 20 Регистрация: 30.10.2010 Пользователь №: 2163 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Iron Bug, во-первых, привет земляку. Я тоже из Екатеринбурга.
Цитата но в примере никакой форвард-декларации нет Форвард-декларация - это такой способ сэкономить время на компилции. Форвард декларация - это простое сообщение о существовании сигнатуры. А декларация - это подробное разъяснение, что за этой сигнатурой скрывается. Форвард-деклараци - это любая функция или класс, в синтаксисе которых отсутствуют фигурные скобки - это основной признак форвад-декларации. Исторически появились как необходимость кросс-вставки классов.
Ну а сегодня, её юзают тупо для сокращения времени компиляции, если есть возможность обойтись одними указателями на класс или функцию, потому что размер указателя вне зависимости от типа есть константа.
Топик начался с того, что для шаблонных классов создание обычной декларации не катит, а как катит я не знал. И тут мне на форуме подсказали супер-мегафичу, которую я домыслил и оказалось, что для шаблонов форвард-декларацией является как бы создание экземлпяра шаблона! + кстати, подсказанный пример можно существенно сократить, выкинув сигнатуры классов в шаблоне KEY, T. Главное - сохранить кол-во классов в шаблоне.
|
|
|
Iron Bug |
![]()
Сообщение
#17
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Исторически появились как необходимость кросс-вставки классов. воот. так что кроме ссылок на самого себя и циклических ссылок это, конечно, можно, но нафиг нигде не нужно. ибо всё,что нужно компилеру - это увидеть описание класса до его использования в коде, что, в случае простого использования класса, достигается вставкой инклюда в одном месте кода, как правило в заголовочнике, где он используется. а в обычном случае, без циклических ссылок, предварительные объявления без инклюда, тем более для стандартно или библиотечно определённых шаблонов, ни к чему, кроме ещё одного лишнего прохода при компиляции, не приводят. куда ты его вставишь - дело десятое. если класс сам по себе используется, то компилятор обработает его один раз. так что "экономия" времени компиляции будет только в случае библиотеки, которая оперирует только указателями и никогда не обращается к самому классу. о да. Столкнулся несколько раз, пытался решить, спрашивал советы - так и оставил в заголовочнике весь шаблон. я как-то тоже напоролась на это. это баг мелкософта. об этом написано где-то в MSDN, только мелким-мелким шрифтом на страничке, которую так просто и не найти ![]() Топик начался с того, что для шаблонных классов создание обычной декларации не катит, а как катит я не знал. И тут мне на форуме подсказали супер-мегафичу, которую я домыслил и оказалось, что для шаблонов форвард-декларацией является как бы создание экземлпяра шаблона! + кстати, подсказанный пример можно существенно сократить, выкинув сигнатуры классов в шаблоне KEY, T. Главное - сохранить кол-во классов в шаблоне. всё объясняется проще: когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. это и есть баг компилера, его несоответствие стандарту. просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован, либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта. Сообщение отредактировал Iron Bug - 31.10.2010, 12:25 |
|
|
Алексей1153 |
![]()
Сообщение
#18
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
экономия времени будет. По крайней мере в студии это очень заметно
![]() Например, класс A (не шаблон), описанный в хедере, не используется в некоем cpp, но из-за вложенности хедеров попал в начало этого cpp. Компилятор его лишний раз скомпилирует (потому что это только у шаблонов не компилируется неиспользыемое). В случае же разнесения кода по A.h и A.cpp , компиляция пройдёт шустрее, так как компилироваться класс A будет всего один раз. Проверить можно так: пусть класс A целиком сидит в A.cpp Можно написать в любой его функции строчку
Везде, где инклуд A.h используется, предупреждение появится (ровно столько же раз, сколько заинклужено) |
|
|
igor_bogomolov |
![]()
Сообщение
#19
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
с MSVC, то нельзя выносить реализацию шаблонного класса из его объявления (это баг MSVC, несовместимость со стандартами). то есть, в заголовочнике должен быть весь класс так и оставил в заголовочнике весь шаблон При чем здесь MSVC? Разделить реализацию и объявление шаблона можно только с использованием ключевого слова export, которое ни один компилятор так и не реализовал. Поэтому для шаблонов подходит только модель включения, т.е. в одном файле должны быть все объявления и определения шаблона. У Вандевурда & Джосатиса это хорошо описано.template<class, class> b; // шаблонный форвард Тут ошибка, должно быть template<class, class> class b;Кстати, по поводу того зачем нужны форвард объявления хорошо описано в этой книге (ссылка) (см. раздел 2.3) --Добавлено чуть позже-------------------------------------------------------------------------- Этого вообще не понял всё объясняется проще: когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. это и есть баг компилера, его несоответствие стандарту. просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован, либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта. Разберем по частям Цитата когда мелкософтовский компилер собирает модули, он считает, что если нет экземпляра шаблонного класса - то его описание можно просто выкинуть. совершенно правильно считаетЦитата просто для MSVC нужно, чтобы либо инклюд был явно включен в файл, где шаблон будет использован а как вы собираетесь использовать класс, если в данном листе трансляции ничего про него не известно? Естественно нужно делать инклуд, и шаблоны тут не при чемЦитата либо вот так вот, как ты описал, извратиться и заставить компилер учесть шаблонный класс методом создания фиктивного объекта какой еще фиктивный объект? Где вы его увидели? Там лишь форвард объявление шаблонного класса, никаких объектов не создается
|
|
|
daorus |
![]()
Сообщение
#20
|
Студент ![]() Группа: Участник Сообщений: 20 Регистрация: 30.10.2010 Пользователь №: 2163 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
достигается вставкой инклюда в одном месте кода У меня почему-то активное использование форвардов существенно экономит время компиляции. + если зависимость от форварда, то изменение в заголовочном файле не генерит флаг на перекомпиляцию. А вообще это просто вопрос привычки. Привык я форвары в хедерах юзать вместо инклудов. :-)всё объясняется проще: когда мелкософтовский компилер а я на g++ работаю. Про msvc вообще ничего не знаю.Тут ошибка, должно быть template<class, class> class b; Да, конечно. Я слишком увлекся идеей. Но почему-то у меня нет кнопки правка сообщений, поэтому баг так и останется висеть в моем посте. :-(с использованием ключевого слова export Если я правильно понял, это вы уже не про хедеры, а про форварды в *.cpp файлах? т.е. типа такого
Вы это имели ввиду? |
|
|
Алексей1153 |
![]()
Сообщение
#21
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2943 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
Привык я форвары в хедерах юзать вместо инклудов. :-) это не должно быть самоцелью. Частенько в этом нет необходимости, но ведёт к затратам времени на разработку плюс учитывание ручного управления памятью. Причины использовать форвард - это кросс-ссылка или большой объём кода. Других причин не вижу )) |
|
|
igor_bogomolov |
![]()
Сообщение
#22
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Но почему-то у меня нет кнопки правка сообщений Появится после 20 сообщений. Если я правильно понял, это вы уже не про хедеры, а про форварды в *.cpp файлах? Это я про разделение объявления шаблонного класса и его реализации по .cpp/.h фалам http://www.cppreference.com/wiki/keywords/export (если конечно я правильно идею понял, попробовать, как вы понимаете, это не получится)Цитата Привык я форвары в хедерах юзать вместо инклудов. :-) Аналогично. Если в классе объявленны только ссылки и указатели, не вижу ни какого смысла делать инклуд, только форвард объявление ![]() |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 15.6.2025, 22:47 |