Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175

Правильное связывание .cpp & .h

21.10.2019, 20:35. Показов 2632. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго всем!
Обращаюсь за советом: как лучше и грамотнее написать?

Есть 2 класса, назовем их класс А и класс В.
Они и все их функции объявлены в А.h и B.h, соответственно.
Реализация функций вынесена в файлы A.cpp и В.cpp, соответственно.
Для сокращения размеров кода в функциях A.cpp и В.cpp, были созданы оптимизирующие функции в С.h

Если я подключаю С.h в А.cpp и B.cpp, соответственно возникает переопределение, так как все срр на этапе компоновки "сливаются", а include просто подставляет определение функций дважды, что влечет за собой LNK2005-Переопределение.

Собсна вопрос: как это можно грациозно обойти, не трогая ни А.h и B.h, ни A.cpp и В.cpp? С.h трогать можно.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.10.2019, 20:35
Ответы с готовыми решениями:

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

Есть три файла. файл main.cpp и Source.cpp знают только Header.h, так как он подключен. как же подключается Source.cpp
main.cpp #include <iostream> #include"Header.h" using namespace std; int main() { A ob; ob.f(); return...

Ошибка: multiple definition of `void std::swap<A>(A&amp;, A&amp;)
Хочу специализировать swap для своего класса. Получаю ошибку. Вот код:#ifndef A_H #define A_H #include &lt;string&gt; class A ...

36
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 21:58
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Battary Посмотреть сообщение
Нуууу, если структура настолько класс, насколько число π=3.
Например даже функционалом дружественности, наследования, конструкторы по умолчанию, копирования, (ещё 1 тип не помню), деструкторы.
Давай, Илон Маск, скомпилируй такое:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct A
{
    int x;
    A()
    {
        x =10;
    }
};
 
struct B : public A
{
 
};
 
 
int main()
{
    B h;
    B m(h);
    std::cout << m.x;
 
    system("pause");
    return 0;
}


Цитата Сообщение от Алексей1153 Посмотреть сообщение
extern void CycleAnimation();
extern void UncycleAnimation();
Зачем тебе extern???
0
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
21.10.2019, 22:01
Folian, это не мне, а компилятору - extern говорит компилятору, что в одном из cpp есть глобальное определение идентификатора
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
21.10.2019, 22:09
Battary, объявления
void CycleAnimation()
void UncycleAnimation()
в заголовочник я бы положил. Это не важно, но для порядку. А уже его заинклудил бы в cpp-шники ваших классов. Фактически в C.h можно оставить объявления, а в C.cpp перенести определения. C.h соответственно, инклудить в во все cpp-шники. Хотя у вас так всё изложено, что не понять не мудрено.
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 22:10
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это не мне, а компилятору
а сам прототип функции не говорит, что где-то должно быть тело?

extern для глобальных объектов/переменных. Функции со своими прототипами сами себя обеспечивают.

Попробуй без extern сделай как сам говоришь. Прототип ( void foo(); ) в хедер, тело ( void foo() {} ) в цпп.
0
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
21.10.2019, 22:13
Folian, справедливости ради, отмечу, что mingw вот так скомпилил

C.h
C++
1
2
3
4
5
6
7
8
9
#pragma once
 
static void CycleAnimation()
{
}
 
static void UncycleAnimation()
{
}
но верещит, что идентификаторы определены, но не использованы. При каких-то условиях у меня, помнится, была ругань на использование одинаковых идентификаторов в похожей ситуации. То ли это в студии с cl было

В общем - ситуация явно не здоровая в таком виде

Добавлено через 2 минуты
Folian, вижу, ты запутался в цитатах. Про "отсутствие тела"+static - это я говорю про статические функции класса (про оболочку, то есть), а не про голые функции
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 22:27
Цитата Сообщение от Алексей1153 Посмотреть сообщение
вижу, ты запутался в цитатах.
вот не надо.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
но верещит, что идентификаторы определены, но не использованы.
они и не использованы. Зачем тебе тут static? Ты ничего и не делаешь с ними.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
если обернуть в класс, то static нужен - так как ты вызываешь без экземпляра.
Зачем класс? И я не об этом.

Цитата Сообщение от Алексей1153 Посмотреть сообщение
Если без обёртки, то так
C++
1
2
3
4
#pragma once
 
extern void CycleAnimation();
extern void UncycleAnimation();
Я об этом. Зачем тебе extern?
0
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
21.10.2019, 22:36
Цитата Сообщение от Folian Посмотреть сообщение
Я об этом. Зачем тебе extern?
разнеси прототип и реализацию по файлам - без extern не скомпилишь, если C.h будет инклудится в несколько cpp
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 22:53
Цитата Сообщение от Алексей1153 Посмотреть сообщение
без extern не скомпилишь
ты понимаешь вообще что делает #include и зачем нужен include guard?

Как же ты упёрт, вместо того чтобы попробовать что-то сделать сидишь и строчишь не пойми чего.

Домашнее задание: создай пару файлов, 1.h и 1.cpp:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//1.h
 
#ifndef _1_H_
#define _1_H_
 
void foo();
 
#endif
//-------------------------
 
//1.cpp
 
#include <iostream>
 
void foo()
{
    std::cout << "fff";
}
 
//----------------------
подключи туда где main 1.h (#include "1.h") и вызови foo();
0
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
21.10.2019, 23:11
Folian, конечно понимаю. Я обычно прагму использую, но в данном случае нет разницы.

Я попробовал - на последнем mingw это компилится, однако я точно помню, что были проблемы без extern где-то. Может, старые компиляторы ругались? Но я такую лапшу давно не делаю, сейчас в классы всё завёрнуто, поэтому я не отслеживаю этот момент. Надо какой-нибудь древний проект поднять протестить

Да и я ж не против, работает, так работает
1
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 23:22
Цитата Сообщение от Алексей1153 Посмотреть сообщение
проблемы без extern где-то.
ещё раз - это про глобальные переменные/объекты. Прототипы функций сами по себе extern.

Я рад что ты понял, держи стакан
1
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
21.10.2019, 23:26
Folian, дык, про объекты и переменные само собой. Я вот сейчас нашёл древний проект, удалил extern у голых функций - скомпилилось. Чудеса
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 23:27
О! Да я и сам тебя внезапно понял! Твой extern может быть употреблён, когда функции нет в хедере (а только в каком-то цпп)! Это может быть, но это не повод пихать extern для функции в *.х!
0
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
21.10.2019, 23:29
Folian, ну это как бы и заменяет ручное прописывание везде во всех cpp дополнительный extern. Просто включаешь заголовок и всё
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 23:31
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Чудеса
это норма
Миниатюры
Правильное связывание .cpp & .h  
0
фрилансер
 Аватар для Алексей1153
6496 / 5727 / 1133
Регистрация: 11.10.2019
Сообщений: 15,289
21.10.2019, 23:32
Folian, свят свят, перед сном такое показывать о_О
0
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
21.10.2019, 23:36
Цитата Сообщение от Алексей1153 Посмотреть сообщение
ну это как бы и заменяет ручное прописывание везде во всех cpp дополнительный extern. Просто включаешь заголовок и всё
Цитата Сообщение от Folian Посмотреть сообщение
Твой extern может быть употреблён, когда функции нет в хедере (а только в каком-то цпп)!
Это я фигню написал(изиняюсь, пьяненький). Не нужен extern. Прототип и так справится.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
22.10.2019, 02:18
Цитата Сообщение от Battary Посмотреть сообщение
Как я понял, inline -аналог макросов, выход выходом, но лучше так не делать.
Если вы хотите держать определения в .h файле (что разумно), именно inline - самый правильный подход.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.10.2019, 02:18

GRF & DEV CPP
Доброго времени суток!Подскажите как в программе на Си/Си++ использовать графы созданные в программе GraphEdit???Нужно захапать поток с...

query='SELECT * FROM resume WHERE ' & ''' & RecSet('place')& ''' & '=' & '''& s_loc &''' & - что не так?
упростил для краткости запрос. в чем ошибка? RecSet - это коннекшн. query='SELECT * FROM resume WHERE ' &amp; ''' &amp;...

Связывание данных (data binding) & ADO
Помогите, плз. Никак не могу заставить привязаться Аксессовскую таблицу к моей ВЕБ-странице. Хочу просто вывести данные из базы в...

error '80020009' &Icirc;&oslash;&egrave;&aacute;&ecirc;&agrave;. /lalala/profile.asp, line 28
При простейшем и сто раз работавшем скрипте, вылетает ошибка! след. содержания error '80020009' ...

Помогите найти драйвера для pci\ven_8086&DEV_266E&SUBSYS_A002145&REV_05\3&13C0B0C5&0&F2
pci\ven_8086&amp;DEV_266E&amp;SUBSYS_A002145&amp;REV_05\3&amp;13C0B0C5&amp;0&amp;F2 Мультимедиа аудиоконтроллер помогите плз найти...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2. Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её. Всё это стресс конечно. Почему?. . .
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот. Ларри Уингет
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru