Скачиваний:
316
Добавлен:
28.03.2021
Размер:
378.53 Кб
Скачать

56. Использование в параметризированных классах аргументов, не являющихся типами. Использование в параметризированных классах аргументов по умолчанию.

В template спецификации для обобщенного класса можно тоже задавать аргументы, не являющиеся типами. Это значит, что в шаблонной спецификации можно указывать на то, что обычно принимающейся в качестве стандартного аргумента, например, аргумент типа int или аргумент-указатель.

На тип параметров, которые не представляют типы, налагаются ограничения. В этом случае разрешено использовать только целочисленные типы, указатели и ссылки. Другие типы не допускаются. Аргументы, которые передаются параметру, не являющемуся типом, должны содержать либо указатель или ссылку на глобальную функцию или объект. Таким образом, эти “нетиповые” параметры следует рассматривать как константы поскольку их значения не могут быть изменены.

Шаблонный класс может по умолчанию определять аргумент, соответствующий обобщенному типу. Тип используемый по умолчанию можно предусмотреть для наиболее употребительного типа данных, позволяя при этом пользователю ваших классов задавать при необходимости нужный тип данных. Для аргументов, которые не представляют тип в template-спецификации, также разрешается задавать значений по умолчанию. Они используются в случае, если при реализации класса значение для такого аргумента явно не указано. Аргументы по умолчанию для "нетиповых" параметров задаются с помощью синтаксиса, аналогичного используемому при задании аргументов по умолчанию для параметров функций.

133. Шаблоны класса и дружественные функции класса. Спецификатор register.

Шаблоны и контейнерные классы:

Шаблоны классов работают точно так же, как и шаблоны функций: компилятор копирует шаблон класса, заменяя типы параметров шаблона класса на передаваемые типы данных, а затем компилирует эту копию. Если у вас есть шаблон класса, но вы его не используете, то компилятор не будет его даже компилировать.

Шаблоны классов идеально подходят для реализации контейнерных классов, так как очень часто таким классам приходится работать с разными типами данных, а шаблоны позволяют это организовать в минимальном количестве кода.

Дружественные функции, которые описываются в параметризованном классе, не являются автоматически параметризованными функциями, т.е. по умолчанию такие функции являются дружественными для всех классов, которые организуются по данному шаблону.

Если friend-функция содержит в своем описании параметр типа параметризованного класса, то для каждого созданного по данному шаблону класса имеется собственная friend-функция.

Спецификатор register может применяться к переменным любых типов. Спецификатор register можно применить только к локальным переменным и формальным параметрам функций. В объявлении глобальных переменных применение спецификатора register не допускается.

Переменные register идеально подходят для оптимизации скорости работы цикла. Как правило, переменные register используются там, где от них больше всего пользы, а именно, когда процесс многократно обращается к одной и той же переменной. Это существенно потому, что в объявлении можно применить спецификатор register к любой переменной, но средства оптимизации быстродействия могут быть применены далеко не ко всем переменным в равной

Хотя в настоящее время применение спецификатора register в значительной мере вышло за его традиционные рамки, практически ощутимый эффект от его применения по-прежнему может быть получен только для переменных целого и символьного типа.

58. Пространство имен. Пространство имен как объявление. Пространство имен как директива. Определение пространства имен. Доступ к элементам пространств имен. Неоднократное определение пространств имен. Неименованные пространства имен.

Пространство имен — это декларативная область, в рамках которой определяются различные идентификаторы (имена типов, функций, переменных, и т. д.). (это определение из Microsoft docs, т.к в конспекте не дописано это определение)

Все идентификаторы в пределах пространства имен доступны друг другу без уточнения. Идентификаторы за пределами пространства имен могут обращаться к членам с помощью полного имени для каждого идентификатора, std::vector<std::string> vec;например или с помощью объявления using для одного идентификатора (using std::string) или директивы using для ALL идентификаторы в пространстве имен (using namespace std;). Код в файлах заголовков всегда должен содержать полное имя в пространстве имен. (это тоже взято из Microsoft docs)

Для того, чтобы получить доступ к переменным пространства имени, можно указывать имя этого пространства, а затем оператор расширения имени. Либо использовать директиву using namespace + имя_пространства.

Можно создавать пространство имен, не задавая имени. Использование пространства имен предпочтительнее, нежели static элементов. Ключевое слово typedef задает новое имя существующим типам данных, не создавая новых.

Не из конспекта:

Директива using разрешает использовать типы из указанного пространства имён, поэтому явное указание пространства имён при использования типа не требуется

Вы можете создать явное пространство имен, но не присвоить ему имя. Это называется безымянным или анонимным пространством имен, и его можно использовать, если нужно сделать объявления переменных невидимыми для кода в других файлах (т. е. обеспечить их внутреннюю компоновку) без создания именованного пространства имен. Весь код, находящийся в том же файле, может видеть идентификаторы в безымянном пространстве имен, но эти идентификаторы, а также само пространство имен, будет невидимым за пределами этого файла или, точнее, вне блока перевода.

59. Многофайловые программы как способ структуризации разрабатываемого программного обеспечения. Структура многофайловых приложений на C/C++. Использование ключевого слова extern, static.

При разработке достаточно больших программ бывает удобным разрабатывать программу не в виде одного файла, а в виде нескольких. В отдельном файле сохраняем функцию main(), подпрограммы — каждую в отдельном файле или группируем по назначению.

Подпрограмма, сохранённая в отдельном файле, может быть очень легко использована в другой программе. Достаточно будет только подключить к проекту новой программы файл с этой подпрограммой.

Переменная, имеющая внутренние связи, называется внутренней переменной (или «статической переменной»). Она может использоваться в любом месте файла, в котором определена, но не относится к чему-либо вне этого файла.

Переменная, имеющая внешние связи, называется внешней переменной. Она может использоваться как в файле, в котором определена, так и в других файлах.

Межфайловые функции.

Объявление функции (или прототип) задает ее имя, тип возвращаемых данных и типы, количество и порядок всех аргументов. Определение функции (реализация) – это объявление функции + тело.

Когда компилятор генерирует вызов функции, ему незачем знать, как она работает. Все что нужно знать компилятору, это имя функции, возвращаемый тип и аргументы. Все это есть в прототипе функции поэтому можно только объявить в одном файле.

Межфайловый класс.

  • Определение класса не резервирует память. Оно информирует компилятор о том, что содержится в этом типе.

  • Компоненты (начинка) класса должны быть объявлены, но не обязательно определены. Определение методов класса чаще всего происходит все класса.

  • Создание объекта подразумевает выделение памяти. Определение статических переменных всегда выносятся за класс, т.к оно связаны с выделением памяти.

  • Невозможно определить класс дважды в одном файле, но каждый исходный файл может иметь собственное определение одного и того же класса.

  • Нельзя определить функцию или переменную в заголовочном файле, который будет использован несколькими файлами, подключаемыми в один файл. Это приводит к ошибкам повторных определений.

  • Для того, чтобы предупредить оишбки повторного включения, необходимо поределение в заголовочном файле начинатьс с директивы препроцессора:

Если не определяем: # if !defined(HEADCOM) ( HEADCOM - любой идентификатор)

Если определяем: # define HEADCOM

Static and extern.

Для того, чтобы переменная, определенная в одном файле была видна в другом, нужно объявлять во всех остальных файлах с помощью зарезервированного слова extern.

Статистические переменные имеют внутренние связывание, нестатические глобальные – внешнее. В многофайловых программах рекомендуется делать глобальные переменные статические. В отличии от глобальных переменных, статические никогда не описываются в хэдер файлах, т.к static и extern конфликтуют между собой.

60. Компоновщик, компилятор. Этапы создания приложения на C/C++. Переименования типов с помощью оператора typedef.

Сама по себе программа на языке С++ представляет собой текстовый файл, в котором представлены конструкции и операторы данного языка в заданном программистом порядке.

Следующий шаг – это компиляция исходного кода. Под компиляцией понимают процесс, при котором содержимое текстового файла преобразуется в исполняемый машинный код, понимаемый процессором компьютера. Однако компилятор создает не готовую к исполнению программу, а только объектный код (файл с расширением *.obj). Этот код является промежуточным этапом при создании готовой программы. Дело в том, что создаваемая программа может содержать функции стандартных библиотек языка С++, реализации которых описаны в объектных файлах библиотек. Например, в приведенной программе используется функция printf() стандартной библиотеки «stdio.h». Это означает, что объектный файл ex1.obj будет содержать лишь инструкции по вызову данной функции, но код самой функции в нем будет отсутствовать.

Для того чтобы итоговая исполняемая программа содержала все необходимые реализации функций, используется компоновщик объектных кодов. Компоновщик – это программа, которая объединяет в единый исполняемый файл объектные коды создаваемой программы, объектные коды реализаций библиотечных функций и стандартный код запуска для заданной операционной системы. В итоге и объектный файл, и исполняемый файл состоят из инструкций машинного кода. Однако объектный файл содержит только результат перевода на машинный язык текста программы, созданной программистом, а исполняемый файл – также и машинный код для используемых стандартных библиотечных подпрограмм и для кода запуска.

Компиля́торэто программа, которая переводит текст, написанный на языке программирования, в набор машинных кодов.Компиляция относится к обработке файлов исходного кода (.c, .cc, или .cpp) и создании объектных файлов проекта. На этом этапе не создается исполняемый файл. Вместо этого компилятор просто транслирует высокоуровневый код в машинный язык.

Зная разницу между фазами компиляции и компоновки вам будет намного проще находить ошибки в своих проектах. Компилятор отлавливает, как правило, синтаксические ошибки — отсутствие точки с запятой или скобок. Если вы получаете сообщение об ошибке, множественного определения функции или переменной, знайте, вам об этом сообщает компоновщик. Эта ошибка может означать только одно, что в нескольких файлах проекта определены одна и та же функция или переменная.

Переименование типов с помощью typedef Зарезервированное слово typedef может оказаться полезным в определенных ситуациях, и вы наверняка встречали его, по крайней мере, в чужих листингах. С его помощью можно создать новое имя для типа данных. Например, выражение

typedef unsigned long unlong;

переименовывает unsigned long в unlong, точнее, делает их синонимами. Теперь можно объявлять переменные с использованием нового имени:

unlong var1, var2;

Это может помочь сэкономить немножко места.