Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Для новичков > [Линковка] Как обратиться к классу, определенному |
Автор: zim22 17.7.2009, 14:44 | ||||
К функции xxx мы обращаться можем из main.cpp. Хотя она и определена в другом файле. Как создать объект класса First в файле main.cpp? (не использую #include и файлы заголовков)
|
Автор: azesmcar 17.7.2009, 14:50 | ||
zim22 Указатель можно создать так
а вот создать обьект - никак без включения заголовочного файла. Откуда ему знать, есть у класса такой конструктор, открыт ли он вообще итд... А это все компилятору нужно знать на этапе компиляции. |
Автор: mes 17.7.2009, 14:54 |
интересно, как для т.с. связано "создание объекта" и "линковка" ? |
Автор: AlexT84 17.7.2009, 14:57 |
Не используя инклуда -- только заново описать класс First. |
Автор: zim22 17.7.2009, 15:48 | ||
я сейчас разбираюсь в том, как происходит сборка программмы из исходников. линковка - один из её этапов. но до линковки не доходит, т.к. исходник даже не компилирууется. ![]() класс определён в одном translation unit использовать его я хочу в другом translation unit значит необходимо обеспечить взаимодействие между юнитами. http://gaubuali.wordpress.com/linkage-in-c-and-c/ сказано следующее:
вы хотите сказать, что нельзя написать программу без использования заголовочных файлов? |
Автор: zim22 17.7.2009, 15:53 | ||
ну а почему с функциями прокатывает? |
Автор: azesmcar 17.7.2009, 15:54 | ||
можно пример, чтобы было понятнее о чем идет речь? Добавлено @ 15:57 подозреваю что речь идет об этом
ну так с классами это тоже прокатывает. Тут указана сигнатура функции, компилятор знает все необходимое об этой функции и может оставить остальное линкеру. Если описать структуру класса - для классов будет тоже самое (в принципе это и происходит при включении заголовочного файла). (непонятно зачем приписал extern, он тут не нужен, убрал). |
Автор: zim22 17.7.2009, 15:57 | ||||
функция определена в другом файле. тем не менее линкер/компилятор её находит.
|
Автор: azesmcar 17.7.2009, 16:02 | ||
zim22 Ну, прототип функции обявлен ведь.
с классами тоже можно. Вот так. А включение заголовочного файла только копирует его содержимое в текущий. |
Автор: zim22 17.7.2009, 16:05 | ||||
у меня не получается. этап линковки не проходит.
|
Автор: azesmcar 17.7.2009, 16:09 | ||||||
file1.cpp
file2.cpp
а вот эту часть
заменяют на #include а саму декларацию выделяют в заголовочный файл. |
Автор: zim22 17.7.2009, 16:11 | ||
большое спасибо! я ж говорил, что можно без #include обходиться ![]() |
Автор: azesmcar 17.7.2009, 16:13 |
А я как будто не соглашался ![]() #include по сути вставляет содержимое одного файла в другой, разумеется без него можно (если делать тоже самое самому) ![]() |
Автор: zim22 17.7.2009, 16:15 | ||||
Почему в случае определения функции внутри класса линкер не находит её?
|
Автор: azesmcar 17.7.2009, 16:19 | ||
zim22 Потому что в этом случае она инлайниться, а инлайн функции как известно должны быть объявлены во всех translation unit-ах. Добавлено через 59 секунд
|
Автор: zim22 17.7.2009, 16:30 | ||||||
т.е. можно переопределять её тело, как это ни печально? и во время объявления класса в main.cpp я изменил его члены данных (определил value типа int) - это тоже прокатило... т.е. это уже два разных класса получается, а не один. хотя и не совсем два - т.к. конструктор у них один - общий... ужас какой-то получается
|
Автор: azesmcar 17.7.2009, 16:37 | ||
точно ![]() а вот насчет этого ужаса
так что то, что это безобразие работает где-то еще ничего не значит ![]() |
Автор: zim22 17.7.2009, 16:48 | ||
ок. с inline функциями разобрался ![]() как насчёт этого:
|
Автор: azesmcar 17.7.2009, 16:52 |
zim22 Ну на С++ есть множество способов извратиться, потому этот язык и считается сложным и именно потому для него написано столько книг. Просто не надо так извращаться ![]() |
Автор: Леопольд 17.7.2009, 17:03 | ||||
Вот это тоже работает, в VC 2008 Express, а не должно: test.cpp
main.cpp
Но при этом выводит 5 в консольке. Не удивлюсь, если g++ откажется это собирать... Не удивлюсь, если соберёт, и выведет 10 ![]() ![]() |
Автор: zim22 17.7.2009, 17:08 | ||
а почему бы ему и не работать. как по мне - обычный код ![]() он и должен 5 выводить. по крайней мере я в уме пошагово прошёл - 5 на выходе оказалось ![]()
|
Автор: Леопольд 17.7.2009, 17:10 | ||
По стандарту, это не должно скомпилироваться. |
Автор: zim22 17.7.2009, 17:14 | ||||||
собирает. без единого warning'a ссылочкой не поделитесь где это в стандарте? *** приведенные вами два cpp файла аналогичны нижеизложенному коду, за одним исключением, в котором вы сами нарушили стандарт: переопределили тело инлайн функции.
|
Автор: Леопольд 17.7.2009, 17:20 | ||||||
azesmcar уже цитировал стандарт Попробуйте заменить main вот на это ![]()
А потом на это
надо будет добавить в main #include <iostream> |
Автор: zim22 17.7.2009, 17:23 | ||
прочитайте ещё раз то, что он цитировал
shall != must |
Автор: Леопольд 17.7.2009, 17:26 | ||||
Однако ворнинга нет... А значит, компилятор забил на этот shall ![]() Добавлено @ 17:30 А вот это даёт разный результат в VC 2008 Express и в gcc 4.3.3 - компиляторам нельзя верить, надо проверять ![]()
|
Автор: zim22 17.7.2009, 17:34 |
да, глюк неприятный. undefined behavior. однако избежать его достаточно просто - не переопределять inline функции ![]() |
Автор: Леопольд 17.7.2009, 17:38 | ||
По старинке, пользоваться #include ![]() |
Автор: mes 17.7.2009, 20:17 |
потому что Вы путаете сущности этапа компиляции и линковки. Для начала исходный код, транслируется в объектный - этап компиляции. На этом этапе Cpp-код лишается всего своего ООП . В итоге объектники cpp, си, паскаля, асма и др. "выглядят" одинаково и из нескольких таких (полученных с разных языков) объектников можно слинковать одну общую прогу. |