Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Некоторые вопросы об ODR, декларации и определениях

Автор вопроса: vincentvangaoghОтветов: 1

Извините, если вопросы старые или немного глупые.

Я знаю основы объявления и определения, но, похоже, в C ++ есть много несоответствий или "исключений", которые делают его не гармоничным, по крайней мере, для меня. Или я что-то неправильно понял.

Итак, в файлах заголовков мы объявляем некоторые переменные и определяем типы классов (также слышали о "объявлении класса", не знаю, какой из них более точный); внутри каждого класса мы объявляем переменные-члены и функции. Затем в каком-нибудь файле .cc / .cpp мы определяем только функции-члены для реализации класса. Если "к сожалению" существует статическая переменная / функция-член, которая будет считаться особой и в значительной степени независимой от связанного класса, ее необходимо определить вне класса, поскольку это единственный вид "уродов". "среди переменных-членов.

Когда файл .cpp #include содержит файл заголовка, который определяет тип класса (обратите внимание, что определение типа класса в этом файле заголовка кажется "неполным", поскольку его функции определены где-то еще.), Файл .cpp помещает определение типа класса в начало вместе с другими возможными объявлениями.

В файле .cpp статические переменные-члены класса #included уже определены в реализации .cpp вместе с функциями-членами, тогда как насчет нестатических "нормальных" переменных-членов, если экземпляр класса создается? Предположим, это Class A;, тогда будут ли определены нестатические переменные-члены, если A a;? Конечно, объект a типа A определен, но его нестатические переменные-члены также определены (определены в том смысле, что выделено памятью)? Если это так, то два объекта, скажем a1 и a2, одного типа A были бы полностью совместимы, чтобы быть вместе, потому что a1.mem_var_1 и a2.mem_var_1 имеют разные определения по отношению к разным именам экземпляров класса? Или у них одно и то же определение, но с разными значениями и копиями?

А как насчет функций-членов? Они были определены в файле .cpp для типа класса, но когда мы создаем несколько экземпляров, разве они не будут иметь одно и то же определение в .cpp, но будут иметь разные копии в памяти (я предполагаю, что несколько копий одной и той же функции-члена необходимы, по крайней мере, для разных значений локальных переменных внутри)? А как насчет статических функций?

ИЛИ, я что-то неправильно понимаю, потому что мы, программисты "определяем" что-то в файле НЕ РАВНО компилятору и компоновщику " определить "что-нибудь в файле? Что на самом деле означает и означает определение? Мы записываем в файл что-то, чтобы "определить" что-то, но система может "определить" по-другому, по крайней мере, в смысле тайного создания нескольких копий и прочего?

Мои головные боли...

  • возможный дубликат В чем разница между определением и декларация? NathanOliver 07.07.2015
  • @ShafikYaghmour Я бы сказал, что он отвечает по крайней мере на половину вопроса, но я бы сказал, что он слишком общий, поскольку это несколько вопросов в одном. Я просто хотел указать OP на хорошую информацию. возможно, мне следовало сказать, что это связано. NathanOliver 07.07.2015
  • Да, отчасти помогает, но не всем. vincentvangaogh 07.07.2015
  • @NathanOliver предоставляет полезную ссылку, которая отвечает примерно на половину вашего вопроса, но поскольку этот вопрос написан, он слишком широк, в нем слишком много вопросов и нет конкретных примеров. Вам необходимо указать конкретную проблему вместе с минимальным, полным и поддающимся проверке примером, который иллюстрирует проблему, если это возможно. Shafik Yaghmour 08.07.2015

c++classdefinitionstatic-membersone-definition-rule

Ответы

Ответ 1 · рейтинг -1 · AndreiM

Причина этого - историческая. Когда был изобретен C, память и процессор были маленькими и дорогими. Если в вашем проекте было 20 файлов, компилятор просто не смог бы загрузить всю память и разрешить символы. Resolve означает выделение достаточного и правильного места для каждой функции, структуры и переменной.

Теперь представьте, что у нас есть 2 файла cpp, один определяет структуру String, а другой определяет структуру Rectangle. Чтобы функции работали со String и Rectangle в обоих файлах, компилятор должен загрузить оба файла и проанализировать их. В те времена это была бы очень интенсивная операция по памяти.

Поэтому некоторые дополнительные файлы, заголовки были приняты. Эти заголовки просто сообщают памяти компилятора информацию о каждом типе, используемом cpp. Затем компилятор может компилировать только на основе файла cpp и всех зависимых заголовков в файлы obj.

После того, как все cpp были скомпилированы, происходит компоновка, в которой собираются все файлы obj. Теперь критически важно, чтобы переменные были определены одинаково для всех cpp, иначе некоторые cpp будут работать с прямоугольником размером 8 байт, а другой cpp будет работать с прямоугольником размером 12 байтов, а когда их объединить -> бац!

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы