| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > unresolved external symbol в *.obj при связывании |
| Автор: KasMP 16.7.2009, 11:42 | ||||||||||||||||
В программе нет ничего особенного: используется самое элементарное из WinAPI, есть *.h с базовым классом (и виртуальными функциями), еще *.h с его наследниками и реализациями этих виртуальных функций, несколько *.cpp с несложными функциями. Нигде ничего особенного не задействуется! Основное содержание файлов, с которыми все это может быть связано:
P.S.. На самом деле у меня все написано очень ровно, столбик к столбику. Не знаю, почему тут все ползет во все стороны... |
| Автор: KasMP 16.7.2009, 13:02 | ||||||||
Действительно... Ты очень умный Моя беда в том, что я часто не дочитываю самые последние пункты главы... А ведь черным по белому написано (несколько раз!):
Или можно поступить хитрее - просто немного определить void Figure :: Draw (HWND hWnd) (ведь хочется на всякий случай иметь возможность создавать объекты типа Figure). Хотя, такие незначащие определения ради самих определний никому не нужны и только все запутывают.
Тоже хорошая мысль |
| Автор: mes 16.7.2009, 13:11 | ||||
Это несколько другая ошибка, и возникла бы если бы ты не переопределила чистую виртуальную функцию в наследниках и попыталась бы создать объект такого типа. В твоем же случае наследники роли не играют. Ты объявила функцию, а тело не написала. В обычной функции выдало бы ошибку только в том случае, если ты где нибудь попыталась бы ее использовать, ну а в случае с виртуальной функцией всегда (так как компилятор должен занести ее адрес в специальную таблицу.) Добавлено через 1 минуту и 28 секунд
пока да, потом поймешь что у абстрактных классов есть свои преимущества. |
| Автор: Леопольд 16.7.2009, 14:43 | ||||||
| Здесь я попытался разобраться со статической и динамической линковкой. Какие-то вопросы закрыл. Но классы не трогал. http://forum.vingrad.ru/forum/topic-263893/anchor-entry1900638/0.html Тут есть свои тонкости: inline функции не подчиняются ODR, у них свои правила; static функции члены линкуются динамически, в отличие от обычных static функций. Это значит что определения static функций членов не следует помещать в заголовочном файле, таким образом можно нарушить ODR если сделать #include в нескольких .cpp файлах проекта (как правило, это разные единицы трансляций). А определения обычных static функций можно без проблем помещать в заголовочных файлах, тогда для каждой единицы трансляции будет свой экземпляр такой функции. Пример: first.h
first.cpp
main.cpp
ODR - One Definition Rule (Правило Одного Определения) Есть и другие аспекты. |
| Автор: zim22 16.7.2009, 16:21 | ||||||||||
почему у меня правило ODR не нарушается? 1) определение static функции помещено в заголовочном файле 2) сделан #include в нескольких cpp файлах проекта (Bar.cpp, main.cpp)
|
| Автор: Леопольд 16.7.2009, 19:17 | ||||
Потому что она inline, и не только из-за квалификатора, а ещё из-за того что определение находится в теле класса. Для inline функций свои правила. Однако, inline static функции члены всё равно, линкуются динамически в отличии от inline static обычных функций, которые линкуются статически. Похоже наврал, они видимо тоже линкуются статически... надо бы проверить в стандарте, но сейчас некогда... А вроде и не наврал |
| Автор: zim22 16.7.2009, 19:22 | ||||||||||
Леопольд, не понимаю. где я сделал что-то не то?
я поместил:
#include сделал в нескольких файлах
почему ODR не нарушается? вы же пишете, что таким образоем его можно нарушить. |
| Автор: Леопольд 16.7.2009, 19:27 | ||||
Что именно непонятно из моего объяснения? Попробуйте сделать так:
|
| Автор: zim22 16.7.2009, 19:36 | ||
сделал. всё компилится без ошибок. и в Студии, и в GCC мне непонятно не ваше объяснение, а ваше утверждение, что
нарушьте его, прошу вас. у меня не получается... |
| Автор: Леопольд 16.7.2009, 19:41 | ||||||||||
first.h
first.cpp
main.cpp
Добавлено через 12 минут и 33 секунды
А у меня получается |
| Автор: zim22 16.7.2009, 21:01 |
| я понял, что не понимаю, как линкуются программы в С++. лучше поздно, чем никогда... |
| Автор: KasMP 17.7.2009, 07:51 | ||||
Да, если заглянуть в переменную типа Point/Line/Ellipse/Rectangle во время выполнения, то в них появляется указатель на Draw()
Поскорей бы |
| Автор: Леопольд 17.7.2009, 08:36 | ||||
C# - Interface. C++ - abstract class. Полезность интерфейса достаточно проста. Например, у разных авто (пожарная, скорая и т.п.) разное предназначение, но есть одинаковый интерфейс - руль, педали, кпп Имея коллекцию указателей-интерфейсов, можно "управлять" разными объектами (с этим общим интерфейсом) на которые они указывают. Логично и то, что нельзя создать объект абстрактного класса, ведь голый интерфес, не "подключенный" ни к чему конкретному ничем не управляет. Как правило, множественное наследование интерфейсов не создаёт проблем. Т.е. у объекта, может быть несколько разных интерфейсов одновременно. |