![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Brodyaga |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 599 Регистрация: 19.1.2008 Репутация: нет Всего: 2 |
Только если эту фразу рассматривать отдельно то может быть, но так как она была в общем разговоре, то ответ на эту фразу отдельно не имеет никакого значения. Фраза имеет смысл только со всеми предыдущими фразами.
Повторю вопрос... Про расширение КАКОГО ИМЕННО файла вы говорите поясняйте пожалуйста?
я всё ПРЕКРАСНО понимаю. Объясните что конкретно вы предлагаете сделать и понятнее.(Если есть предложения кроме как размещать всё в h файле). Под ПОНЯТНЕЕ я имею ввиду привести ИМЯ файла в котором нужно поменять расширение или инклуд(если второе, то на какой инклуд). |
||||||
|
|||||||
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Совершенно неохота спорить. Твое желание правильно реализуется с помощью экспорта шаблонов, о котором я и написал. Не нравиться ответ - игнорируй. В мои обязанности не входит предоставление 100% точной информации. Отвечаю насколько позволяет время по собственному желанию.
про расширение myclass.cpp, cpp файла который ты инклудишь и компилируешь.
![]() 1. Я предлагаю писать шаблонные функции в заголовочном файле (это я рекомендую, это не криво. Так написан весь STL) 2. Если не хочешь - я предлагаю сменить расширение своего файла (myclass.cpp) на myclass.h например или убери его из проекта вообще, чтобы не компилировался. (правый клик мышки на файле в solution explorer, rename/delete). |
||||
|
|||||
Brodyaga |
|
||||||||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 599 Регистрация: 19.1.2008 Репутация: нет Всего: 2 |
дык какой мне смысл от ответа на одну фразу из всего разговора, которая сама по себе отдельно для меня не интересна?
я и не говорю что ты обязан. Ладно.. замяли, действительно бесполезный спор.
вот теперь ясно что про myclass а не myclassinst.
Сейчас , после того как пояснил нормально всё понятно. Итоги:
Этот вариант рабочий, но мне почему то не нравится. Ессно я сделаю так если по другому не получится.
Если ты имеешь ввиду в файле myclassinst сменить инклуд myclass.cpp на myclass.h, то я говорю, что так работать не будет. Студия ругается на то что шаблон явно не инстанцирован.
Так работает тоже. но так уж точно както криво. А как вы относитесь к варианту добавить строки template ClassA* MyClass::MyFunc<ClassA>(ClassA* object); template ClassB* MyClass::MyFunc<ClassB>(ClassB* object); в файл myclass.cpp ? |
||||||||||||||
|
|||||||||||||||
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Очень зря, это вполне нормально. Не совсем понял о чем речь. Конечно криво. Смотри. Что делает include? ничего особенного, просто берет содержимое одного файла и копирует в другой (грубо говоря). Т.е. вместо #include "myclass.cpp" у тебя будет содержимое файла myclass.cpp и дальше какие-то строки, не важно. Что у тебя в файле myclass.cpp?
остальное не важно. Получается что компилятор компилирует два файла myclass.cpp и myclassinst.cpp в обоих из них во время компиляции (поскольку include препроцессорная директива, она работает до компиляции) будет ДВА тела конструктора и деструктора. Для компилятора это не проблема, потому как он компилирует каждый cpp файл по отдельности и делает из них obj файлы. А потом наступает очередь линкера, он соединяет эти два obj файла и видет в обоих из них тело конструктора и деструктора того же класса. Потому и ошибка "already defined". Это о причине возникновения ошибки. Теперь о решении Если писать объявление в заголовочном файле а тело в cpp - это нормально, но в случае с шаблонным классом или функциями этого сделать не получиться (как я уже сказал, экспорт шаблонов). А делать include cpp файл неправильно. Если хочешь просто разделить их, сделай два .h файла. myclass.h и myclass_impl.h и включай у себя в программе только myclass_impl.h (который в свою очередь включает myclass.h. Так ты просто разделишь их на два файла. Вот так. Это сообщение отредактировал(а) azesmcar - 28.7.2009, 12:45 |
||||
|
|||||
Леопольд |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Brodyaga, вот небольшой пример.
Вывод:
Подсказка: функции линкуются динамически, аргумент по умолчанию статически. Если подсказка не объясняет почему так происходит, значит надо уделить немного внимания линковке Судя по Вашим топикам, Вы очевидно не знаете что такое ODR - One Definition Rule (Правило Одного Определения) -------------------- вопросов больше чем ответов |
||||
|
|||||
Brodyaga |
|
||||||||||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 599 Регистрация: 19.1.2008 Репутация: нет Всего: 2 |
ну если ты предлагаешь файл myclassinst.cpp сделать таким:
то так работать не будет.
Это я уже понял после поста UnrealMan'а ![]()
в случае с шаблонным классом получается как раз таки через способ что я приводил в каком то из предыдущих постов.
Вот гдето я видел что так делается, поэтому и так сделал у себя... К сожаление не смог сейчас найти где это видел.. так что соглашусь. А как всё-таки вам способ с включением строк
в файл myclass.cpp ? |
||||||||||||||||
|
|||||||||||||||||
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Я этого не предлагал. Я только две вещи предложил, оба с этим не имеют ничего общего.
нет, мы говорим о разных вещах. Почитай о translation юнитах.
Ну мало ли кто как пишет. Всего повторять не надо, даже микрософтовские заголовки и функции зачастую не пример для подражания. Хочешь пример качественного кода? Смотри boost ![]() Я только ЗА 1-ый вариант, включить все в заголовочный файл. Ну или хотя бы вот этот |
||||
|
|||||
Brodyaga |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 599 Регистрация: 19.1.2008 Репутация: нет Всего: 2 |
ну вот же я указывал... myclass.h
myclass.cpp
myclassinst.cpp
Шаблонный класс разнесён на определение и реализацию. и явное инстанцирование применяю и всё работает! Зачем тогда вообще явное инстанцирование нужно, если вы говорите, что надо просто тупо помещать всё в h файл и всё ок без него работает!??! |
||||||||
|
|||||||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
В C++ есть много чего, что не используется на практике. Хотя бы потому, что надобности нет. Ну вот объясни мне, зачем в твоем случае это нужно? Что это тебе дает кроме проблем? (проблема в том, что вместо того чтобы дописать код, ты целый день это обсуждаешь..ну чем не проблема?). Тебе обязательно надо использовать все возможности, которые дает C++ в одной своей программе? Скажи мне о преимуществах твоего варианта по отношению к моему (как ты выразился: тупо поместить все в .h файле). Это сообщение отредактировал(а) azesmcar - 28.7.2009, 15:12 |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Это абсолютно тоже самое, что полностью перенести весь файл myclass.cpp в myclass.h и сделать #include "myclass.h" Brodyaga, почитай про раздельную компиляцию, дело говорю. ![]() Какая здесь связь, между явным инстанцированием и вынесением реализации шаблонов в отдельный модуль (которая почти ничем не поддерживается)??? Зачем вообще применять явное инстанцирование без насущной необходимости??? Это сообщение отредактировал(а) Леопольд - 28.7.2009, 17:55 -------------------- вопросов больше чем ответов |
|||
|
||||
Леопольд |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Brodyaga, сможешь объяснить почему foo<int>() выводит 0, а foo<char>() выводит 1?
first.h
main.cpp
first.cpp
Это сообщение отредактировал(а) Леопольд - 28.7.2009, 18:11 -------------------- вопросов больше чем ответов |
||||||
|
|||||||
Brodyaga |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 599 Регистрация: 19.1.2008 Репутация: нет Всего: 2 |
Этот код я всеровно сейчас не пишу, другим пока занимаюсь. Поэтому можно и пообсуждать ![]()
Ну положено же разносить определение и реализацию в разные файлы. В моём случае так и получается. А то както некрасивше, когда некоторые классы разнесены, а не которые нет...
Конкретно между ними - никакой. Просто я хочу и то и то сделать. Я не говорю что явное инстанцирование это обязательно разнесение! Я говорю что с помощью него можно сказать компилятору какое воплощение будет у шаблона, если шаблон разнесён по файлам, так как если шаблон в одном файле, то не надо говорить компилятору какое воплощение будет. |
||||||
|
|||||||
azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Кто это так положил? Для шаблонных функций и классов так не положено, я об этом твержу 2 страницы. Посмотри как сделан boost, STL. Не положено так. Но раз тебя это так заботит, скажи мне зачем так положено? Почему лучше разносить определение и реализацию в разные файлы? Что это дает и почему так рекомендуется?
Не вижу ничего некрасивого. |
||||
|
|||||
Леопольд |
|
||||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Brodyaga, это не так. Дело не в том что положено, а в том как тебе нужно. Следующий пример содержит ошибки, потому-что static функции линкуются статически - на этапе компиляции (однако, это не относится к static методам (функциям) класса). Функции с квалификатором inline - вообще отдельная тема. Если же убрать вызовы foo1 и foo2 из main, то всё будет работать. Что бы узнать почему так, читай про раздельную компиляцию. header.h
second.cpp
first.cpp
Заметил, что ты всё же мельком просматриваешь мои посты. Рекомендую уделить им чуть больше внимания. Добавлено через 13 минут и 50 секунд
![]() Может всё же сначала ознакомишься с вопросом, прежде чем пытаться что-то делать? Это будет гораздо быстрее, чем "медотом тыка". Реализацию функций выносят в отдельный cpp файл отнюдь не ради красоты, а для РАЗДЕЛЬНОЙ КОМПИЛЯЦИИ. Насколько мне известно, к шаблонам это относиться в той же степени. Это сообщение отредактировал(а) Леопольд - 29.7.2009, 10:16 -------------------- вопросов больше чем ответов |
||||||||||
|
|||||||||||
Brodyaga |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 599 Регистрация: 19.1.2008 Репутация: нет Всего: 2 |
РАЗДЕЛЬНАЯ КОМПИЛЯЦИЯ ФОРЕВЕР! Все дружно начинаем молиться на неё!!! ![]()
а я не понимаю к чему столько флуда про раздельную компиляцию и какие то непонятные вопросы мне о ней. Если чтото конкретно хочешь по моему примеру сказать, то скажи.
Чтобы подключать определения определённых классов в местах где они нужны и чтобы вместе с ними не подключалась каждый раз вся реализация. Или если изменится чтото только в реализации, то придётся перекомпилировать и слинковать только её. Ну вообщем.. раздельная компиляция (Леопольд! ВНИМАНИЕ! ![]()
Ну хорошо... а чем не нравится метод включения строк template ClassA* MyClass::MyFunc<ClassA>(ClassA* object); template ClassB* MyClass::MyFunc<ClassB>(ClassB* object); в файл myclass.cpp ? Это сообщение отредактировал(а) Brodyaga - 29.7.2009, 14:56 |
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |