Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
 Аватар для JohnBlack123
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520

Чем опасно множественное подключение библиотеки к программе?

15.04.2019, 16:33. Показов 3864. Ответов 18

Author24 — интернет-сервис помощи студентам
Добрый день. Хочу задать вопрос касательно своего проекту.
У меня есть структура, например структура фрукта, которая отведена в отдельный файл-хедер вместе внутренними функциями.
Также есть библиотека, в которой написаны функции для работы с массивом фруктов и библиотека, в которой написаны функции для работы с бинарным файлом (файловая база данных). В последних двух либах подключена библиотека структуры и обе они подключены к программе.
Схематически выглядит это примерно так:
Code Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Fruit.h{
// структура фрукта
}
FruitArray.h{
#include "Fruit.h"
// работа с массивом фруктов
}
FruitDatabase.h{
#include "Fruit.h"
// работа с бинарным файлом 
}
 
Main.cpp{
// ...
#include "Fruit.h" // по идее можно не подключать тут,
// поскольку вызваны FruitArray.h и FruitDatabase.h
#include "FruitArray.h"
#include "FruitDatabase.h"
// ...
}
Собственно сам вопрос. Получается, что в Main.cpp я трижды подключаю Fruit.h , поскольку подключаю его отдельно и вызываю либы, в которых он подключен.
Как это может сказаться на проекте? Хорошо это или плохо? Как можно это исправить?
Спасибо.
1
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.04.2019, 16:33
Ответы с готовыми решениями:

Подключение библиотеки к программе
В общем, требуется подключить библиотеку к программе (primer.lib) и в этой библиотеке должны быть функции: read - чтение числа с...

Опасно ли использовать подключение к FTP?
Добрый вечер! В Windows Forms используется подключение к фтп серверу, безопасно ли это? Можно ли как-то имея только *.exe файл, дабыть...

Чем опасно высокое напряжение?
Господа ответе мне на один вопросик ( Чем опасно высокое напряжение ?)

18
 Аватар для eva2326
1663 / 492 / 106
Регистрация: 17.05.2015
Сообщений: 1,502
15.04.2019, 16:38
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Как это может сказаться на проекте?
Никак (если по уму реализовано)

Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Хорошо это или плохо?
Это - совершенно нормальная повсеместная практика.
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
15.04.2019, 17:04
JohnBlack123, #pragma once
0
 Аватар для JohnBlack123
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
15.04.2019, 17:06  [ТС]
rikimaru2013, эта строчка у меня добавлена в хедерах
0
 Аватар для COKPOWEHEU
4051 / 2602 / 432
Регистрация: 09.09.2017
Сообщений: 11,577
15.04.2019, 17:13
Лучший ответ Сообщение было отмечено JohnBlack123 как решение

Решение

Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Собственно сам вопрос. Получается, что в Main.cpp я трижды подключаю Fruit.h , поскольку подключаю его отдельно и вызываю либы, в которых он подключен.
Это совершенно нормально, и чтобы не получать негативные последствия, придумали такую штуку как защитные define'ы:
some_file.h
C Скопировано
1
2
3
4
#ifndef SOME_FILE_H
#define SOME_FILE_H
...
#endif
Кстати, если захотите использовать заголовочный файл и в Си и в С++ коде, можно написать так:
C Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef SOME_FILE_H
#define SOME_FILE_H
#ifdef __cplusplus
  extern "C" {
#endif
 
  ...
 
#ifdef __cplusplus
  }
#endif
#endif
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
JohnBlack123, #pragma once
Если я правильно помню, эта штука поддерживается не всеми компиляторами.
Лучше ее использовать совместно с защитными define'ами, друг другу они не мешают.
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
15.04.2019, 17:27
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если я правильно помню, эта штука поддерживается не всеми компиляторами.
Ну, такое
Pragma once portability
1
 Аватар для eva2326
1663 / 492 / 106
Регистрация: 17.05.2015
Сообщений: 1,502
15.04.2019, 17:37
Лучший ответ Сообщение было отмечено JohnBlack123 как решение

Решение

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Если я правильно помню, эта штука поддерживается не всеми компиляторами.
Проблема не в портабельности.
Прагму поддерживают все промышленные компиляторы.

Проблема прагмы в принципе действия самой прагмы.
Когда компилятор видит:
C++ Скопировано
1
#pragma once
Он запоминает путь к этому файлу.
В следующий раз он уже не подключит заголовок связанный с этим файлом.
Однако, если у вас в проекте два разных файла с одним и тем же содержимым,
то #pragma once его благополучно пропустит,
и тогда вы будете ловить ошибки из-за множественного определения (в лучшем случае),
либо глюки из-за ошибок ODR (в худшем случае).

Пример:
Нужно покрыть юнит-тестами header-only библиотеку stringed.h
Однако, этот файл включен в состав Google Test Framework.

Получается:
Одна копия файла цепляется вместе с gtest:
C++ Скопировано
1
#include <gtest/gtest.h> // внутри себя прицепляет <gtest/stringed.h>
Другая копия файла - это собственно файл оригинальной библиотеки,
которую нужно протестировать:
C++ Скопировано
1
2
// tools/test/test_stringed.cpp
#include <tools/stringed.h>
Два совершенно одинаковых по имени и содержимому файла.
Но это - два разных файла.
В результате - ошибка множественного определения.

Гварды на дефайнах пропроцессора не страдают от такого деффекта.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Лучше ее использовать совместно с защитными define'ами, друг другу они не мешают.
Я всегда так делаю)
4
 Аватар для JohnBlack123
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
15.04.2019, 17:50  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Лучше ее использовать совместно с защитными define'ами, друг другу они не мешают.
Если я правильно Вас понял, то в моей библиотеке "Fruit_Array.h" в начале должны быть такие строки:
C++ Скопировано
1
2
3
4
5
6
7
#pragma once
 
#ifndef FRUIT_ARRAY_H
#define FRUIT_ARRAY_H
#endif
 
// ...
А за что макрос FRUIT_ARRAY_H отвечает?
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
15.04.2019, 18:01
Цитата Сообщение от eva2326 Посмотреть сообщение
Гварды на дефайнах пропроцессора не страдают от такого деффекта
Если у тебя в разных каталогах есть файлы с одним и тем же именем file.h, и его ты защитил макросом с одним и тем же именем FILE_H, то пострадают

Добавлено через 1 минуту
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
А за что макрос FRUIT_ARRAY_H отвечает?
https://www.cyberforum.ru/faq/... ost4134774
0
 Аватар для eva2326
1663 / 492 / 106
Регистрация: 17.05.2015
Сообщений: 1,502
15.04.2019, 18:02
Цитата Сообщение от Evg Посмотреть сообщение
Если у тебя в разных каталогах есть файлы с одним и тем же именем file.h, и его ты защитил макросом с одним и тем же именем FILE_H, то пострадают
Да неужели? И каким же образом?
0
15.04.2019, 18:04

Не по теме:

Цитата Сообщение от JohnBlack123 Посмотреть сообщение
А за что макрос FRUIT_ARRAY_H отвечает?
За базар. То есть, он формален и уникален. Главное не пересечься с таким же в совершенно другом файле. :D

0
 Аватар для COKPOWEHEU
4051 / 2602 / 432
Регистрация: 09.09.2017
Сообщений: 11,577
15.04.2019, 19:08
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
А за что макрос FRUIT_ARRAY_H отвечает?
Просто константа, которую вы объявляете (#define) если она не была объявлена кем-то раньше.
Идея в том, что при начале компиляции не объявлено ни одной макроконстанты. При первом включении fruit_array.h компилятор (вообще-то, препроцессор, но не важно) смотрит объявлена ли FRUIT_ARRAY_H. Она не объявлена, так что выполняется тело #ifndef. Первой же операцией эта константа объявляется, так что при следующем включении компилятор посмотрит #ifndef FRUIT_ARRAY_H и, поскольку условие ложное, не станет включать тело #if'а.
Цитата Сообщение от eva2326 Посмотреть сообщение
Да неужели? И каким же образом?
Наверное, имеется в виду два файла с разным содержимым и одинаковыми гвардами. Тогда будет включен только первый, а второй потеряется.
2
 Аватар для JohnBlack123
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
15.04.2019, 19:14  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
не станет включать тело #if'а.
Значит ли это то, что мне нужно в тело пихать весь код хедера? Или это касательно константы FRUIT_ARRAY_H?
Спасибо большое !
0
 Аватар для eva2326
1663 / 492 / 106
Регистрация: 17.05.2015
Сообщений: 1,502
15.04.2019, 19:32
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Наверное, имеется в виду два файла с разным содержимым и одинаковыми гвардами.
От клинического идиотизма нет лекарства.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
15.04.2019, 19:34
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Значит ли это то, что мне нужно в тело пихать весь код хедера?
Это изврат (имхо). Хотя если больше нечего, то... Но это крайний случай. JohnBlack123, тело оствим в покое. Директива #include не выполнится если условие компиляции не позволит.
1
 Аватар для JohnBlack123
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
15.04.2019, 19:45  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Это изврат (имхо)
Не спорю, а вот википедия так не думает.
Они приводят пример своей библиотеки "grandparent.h" и пишут для нее такой код:
C++ Скопировано
1
2
3
4
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
// ... contents of grandparent.h
#endif /* !GRANDPARENT_H */
То бишь, пихают код либы прямо в #if.
0
 Аватар для Folian
1710 / 1110 / 337
Регистрация: 25.01.2019
Сообщений: 2,910
15.04.2019, 19:49
Лучший ответ Сообщение было отмечено JohnBlack123 как решение

Решение

Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Значит ли это то, что мне нужно в тело пихать весь код хедера?
В большинстве случаев - да. (если не требуется что-то хитрозадое, придумать пример не могу даже)
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
касательно константы FRUIT_ARRAY_H
Оно и определяется именем файла для уникальности обычно

C++ Скопировано
1
2
3
4
5
6
7
8
#ifndef _file_ /*если не определёна _file_*  :/
#define _file_ /*определяем штуку и далее */
 
/*подставляем тутошний код в цпп, куда хедер инклюдится*/
...
 
#endif /*завершение ifndef*/
/*А если определена _file_ - значит там уже оно есть(повторный #include или, как выше написано, одинаковые #define для разных файлов) и ничего не делается*/
include guard - это так называется вроде;

Касательно #pragma once - никогда не использую, хотя VS предлагает иногда
1
 Аватар для JohnBlack123
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
15.04.2019, 19:55  [ТС]
Folian, Получается реализовав для каждой либы include guard, я могу обезопасить ошибки их множественного определения в Main.cpp и могу не боясь использовать их. Верно?
Или же достаточно будет сделать это в хедере со структурой?
Спасибо!
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
15.04.2019, 20:37
Добавлено через 2 минуты
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
То бишь, пихают код либы прямо
Это обычно инклудят хотя вручную тоже можно, в принципе. Сути это не меняет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.04.2019, 20:37
Помогаю со студенческими работами здесь

Чем опасно предупреждение 8118?
Всем здравствуйте. Поместил на форму компонент TCCalendar. В заголовок формы добавилось: #include &quot;ccalendr.h&quot; ...

Чем опасно использовать Denwer в сети?
Например, настроил загрузку файлов сервера CS:GO с моего IP адреса. В браузере по XX.XXX.XX.XX (Мой IP адрес) доступны файлы сервера,...

Множественное подключение к БД
Пишу программу, суть которой заключается во множественном обращении к БД. БД = .mbd (Access). Есть БД. БД расположена на...

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

Множественное подключение к БД Access
1. Имеется БД Access, в программе помимо своей работы с БД через ADOConnection имеется работа с БД, осуществляемая через потоки. Следуя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Работа с объемным DOM в javascript
Htext 04.04.2025
Сегодня прочитал статью тут о расходах памяти в JS, ее утечках и т. п. И вот что вспомнил из своей недавней практики. Может, кому пригодится. Хотя, в той статье об этом тоже есть. Дело в том, что я. . .
Оптимизация производительности Node.js с помощью кластеризации
run.dev 04.04.2025
Масштабирование приложений для обработки тысяч и миллионов запросов — обыденная задача для многих команд. Node. js, благодаря своей асинхронной событийно-ориентированной архитектуре, стал популярной. . .
Управление зависимостями в Python с Poetry
py-thonny 04.04.2025
Стандартный инструмент для установки пакетов в Python - pip - прекрасно справляется с базовыми сценариями: установил пакет командой pip install и используешь его. Но что произойдёт, когда разные. . .
Мониторинг с Prometheus в PHP
Jason-Webb 04.04.2025
Prometheus выделяется среди других систем мониторинга своим подходом к сбору и хранению метрик. В отличие от New Relic, который использует агентный подход и отправляет данные во внешнее хранилище,. . .
Пакет Context в Golang: Управление потоками и ресурсами
golander 04.04.2025
Работа с горутинами в Go часто напоминает управление непослушными детьми - они разбегаются кто куда, делают что хотят и не всегда завершаются вовремя. К счастью, в Go 1. 7 появился пакет context,. . .
Контейнеризация React приложений с Docker
Reangularity 03.04.2025
Контейнеризация позволяет упаковать приложение со всеми его зависимостями в автономный контейнер, который можно запустить на любой платформе с установленным Docker. Это существенно упрощает процессы. . .
Свой попап в SwiftUI
mobDevWorks 03.04.2025
SwiftUI, как декларативный фреймворк от Apple, предоставляет множество инструментов для создания пользовательских интерфейсов. В нашем распоряжении есть такие API как alerts, popovers, action sheets. . .
Антипаттерны микросервисной архитектуры
ArchitectMsa 03.04.2025
Хорошо спроектированная микросервисная система может выдержать испытание временем, оставаясь гибкой, масштабируемой и устойчивой к большинству проблем. Такая архитектура обладает высоким уровнем. . .
std::mutex в C++: Советы и примеры использования
bytestream 03.04.2025
std::mutex - это механизм взаимного исключения, который гарантирует, что критический участок кода выполняется только одним потоком в каждый момент времени. Это простое, но могущественное средство. . .
Не удержался от оценки концепции двигателя Стирлинга.
Hrethgir 03.04.2025
Сколько не пытался - она выдавала правильные схемы, причём случайно рисовала горячие области в середине, холодные по краям, трубки с краёв в низ и магнит в соединяющей, но при этой выдавала описание. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер