Разделение кода на модули (С++)

Форум для программистов

Разделение кода на модули (С++)

Сообщение dAnIK SeNT » Сб фев 22, 2003 3:41 pm

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

file1.h
Код: выделить все

#pragma once

#if !defined(FILE1_INCLUDED_)

#define FILE1_INCLUDED_



char

 *file1Var1 = "string 1",

 *file1Var2 = "string 2";



#define FILE1_MACRO1 "macro 1"

#define FILE1_MACRO2 "macro 2"



int file1func1(int arg1);



#endif // !defined(FILE1_INCLUDED_)



file1.cpp:
Код: выделить все

#include <windows.h>

#include "file1.h"



int file1func1(int arg1){

 return MessageBox(0, FILE1_MACRO1, file1Var2, MB_OK | MB_ICONHAND);

}



main.cpp:
Код: выделить все

#include <windows.h>

#include "file1.h"

...



При компиляции под Visual C++ 6.0 возникают ошибки:
file1.obj : error LNK2005: "char * file1Var2" (?file1Var2@@3PADA) already defined in main.obj
file1.obj : error LNK2005: "char * file1Var1" (?file1Var1@@3PADA) already defined in main.obj
Debug/mytemplate.exe : fatal error LNK1169: one or more multiply defined symbols found

Кто-нибудь может объяснить, в чем тут дело?
яНЯЕД ОН СОПЪФЙЕ: Athlon 64 X2 5200+ @2,86GHz / nF 570 SLI (ASUS M2N SLI Deluxe) / 4 Gb RAM (4x1Gb Kingston) / 2,9Tb SATAII (0,50+0,64+0,75+1,00Tb WD) / ASUS 8800 GTS512 / 2x NEC-Optiarc AD-7173 / Thermaltake ToughPower 650W / 2x30W Microlab Solo-2 / 20" LCD Benq FP202W (wide) / openSUSE 11.1 / KDE 4.2.1
<!--coloro:Navy--><span style="color:Navy"><!--/coloro-->оН БЯЕЛ БНОПНЯЮЛ - Б email. б ICQ ОНЪБКЪЧЯЭ ПЮГ Б ОНКЦНДЮ.<!--colorc--></span><!--/colorc-->
dAnIK SeNT
Маршал
 
Сообщений: 5101
Зарегистрирован: Чт мар 28, 2002 7:48 pm
Откуда: яяяп
Пункты репутации: 0

Сообщение ghostwheel » Сб фев 22, 2003 5:10 pm

#pragma once работает не так как ты думаешь - она защищает от повторного включать в том же файле а не в двух разных файлах. Она просто позволяет компилятору избегать сканирования на #endif.

В результате file1Var2 и file1Var1 определены в main.cpp и file1.cpp одновременно.
ghostwheel
Ст. сержант
 
Сообщений: 44
Зарегистрирован: Пт дек 27, 2002 10:54 pm
Пункты репутации: 0

Сообщение dAnIK SeNT » Сб фев 22, 2003 10:31 pm

2ghostwheel
Что с #pragma once, что без нее - один фиг.
Либа ошибка при компоновке, либо переменные file1Var1, file1Var2 не видны из file1.cpp.
яНЯЕД ОН СОПЪФЙЕ: Athlon 64 X2 5200+ @2,86GHz / nF 570 SLI (ASUS M2N SLI Deluxe) / 4 Gb RAM (4x1Gb Kingston) / 2,9Tb SATAII (0,50+0,64+0,75+1,00Tb WD) / ASUS 8800 GTS512 / 2x NEC-Optiarc AD-7173 / Thermaltake ToughPower 650W / 2x30W Microlab Solo-2 / 20" LCD Benq FP202W (wide) / openSUSE 11.1 / KDE 4.2.1
<!--coloro:Navy--><span style="color:Navy"><!--/coloro-->оН БЯЕЛ БНОПНЯЮЛ - Б email. б ICQ ОНЪБКЪЧЯЭ ПЮГ Б ОНКЦНДЮ.<!--colorc--></span><!--/colorc-->
dAnIK SeNT
Маршал
 
Сообщений: 5101
Зарегистрирован: Чт мар 28, 2002 7:48 pm
Откуда: яяяп
Пункты репутации: 0

Сообщение ghostwheel » Вс фев 23, 2003 12:03 am

<!--QuoteBegin--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>QUOTE </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->2ghostwheel
Что с #pragma once, что без нее - один фиг.
Либа ошибка при компоновке, либо переменные file1Var1, file1Var2 не видны из file1.cpp.<!--QuoteEnd--></td></tr></table><span class='postcolor'><!--QuoteEEnd-->

Конечно ошибка - я же не сказал что убирание #pragma once все исправит - я просто указал на неправильный ход мыслей. Суть ошибки - глобальные переменные везде кроме одного файла должны быть объявлены как extern. Ну ладно - не буду больше извращаться - один из вариантов ниже.

file1.h
Код: выделить все

#pragma once

#if !defined(FILE1_INCLUDED_)

#define FILE1_INCLUDED_



#ifdef __MAIN__



char

 *file1Var1 = "string 1",

 *file1Var2 = "string 2";



#else



extern char *file1Var1, *file1Var2;



#endif



#define FILE1_MACRO1 "macro 1"

#define FILE1_MACRO2 "macro 2"



int file1func1(int arg1);



#endif // !defined(FILE1_INCLUDED_)



file1.cpp - без изменений

main.cpp
Код: выделить все

#define __MAIN__



#include <windows.h>

#include "file1.h"

...



Можно проще, но выше вероятность ошибки при большом количестве глобальных переменных:

file1.h
Код: выделить все

#pragma once

#if !defined(FILE1_INCLUDED_)

#define FILE1_INCLUDED_



extern char *file1Var1, *file1Var2;



#define FILE1_MACRO1 "macro 1"

#define FILE1_MACRO2 "macro 2"



int file1func1(int arg1);



#endif // !defined(FILE1_INCLUDED_)



main.cpp
Код: выделить все

#include <windows.h>

#include "file1.h"



char

 *file1Var1 = "string 1",

 *file1Var2 = "string 2";





Выбирай что хочешь - стиль написания это отдельный вопрос. Некоторые глобальные переменные (не статические) вообще за порок считают. <!--emo&:)-->Изображение<!--endemo-->
ghostwheel
Ст. сержант
 
Сообщений: 44
Зарегистрирован: Пт дек 27, 2002 10:54 pm
Пункты репутации: 0

Сообщение dAnIK SeNT » Вс фев 23, 2003 6:59 am

Большое спасибо, попробую.
А насчет глобальных переменных - у меня есть некоторые глобальные настройки программы (скажем оформление - цвета, шрифты и т.п.). Я хочу держать их в отдельном файле, вместе с функциями сохранения/загрузки, т.к. забивать этим основной файл желания нету. Что мне - для извлечения каждой настройки функцию делать? Или класс может быть? <!--emo&:)-->Изображение<!--endemo-->
Этот файл используется единственный раз - включенным в основной файл, т.е. я разделил код на 2 файла не для повторного использования кода, а для прозрачности.
яНЯЕД ОН СОПЪФЙЕ: Athlon 64 X2 5200+ @2,86GHz / nF 570 SLI (ASUS M2N SLI Deluxe) / 4 Gb RAM (4x1Gb Kingston) / 2,9Tb SATAII (0,50+0,64+0,75+1,00Tb WD) / ASUS 8800 GTS512 / 2x NEC-Optiarc AD-7173 / Thermaltake ToughPower 650W / 2x30W Microlab Solo-2 / 20" LCD Benq FP202W (wide) / openSUSE 11.1 / KDE 4.2.1
<!--coloro:Navy--><span style="color:Navy"><!--/coloro-->оН БЯЕЛ БНОПНЯЮЛ - Б email. б ICQ ОНЪБКЪЧЯЭ ПЮГ Б ОНКЦНДЮ.<!--colorc--></span><!--/colorc-->
dAnIK SeNT
Маршал
 
Сообщений: 5101
Зарегистрирован: Чт мар 28, 2002 7:48 pm
Откуда: яяяп
Пункты репутации: 0

Сообщение dAnIK SeNT » Вс фев 23, 2003 11:52 am

Сенкс, все пашет <!--emo&:)-->Изображение<!--endemo-->
яНЯЕД ОН СОПЪФЙЕ: Athlon 64 X2 5200+ @2,86GHz / nF 570 SLI (ASUS M2N SLI Deluxe) / 4 Gb RAM (4x1Gb Kingston) / 2,9Tb SATAII (0,50+0,64+0,75+1,00Tb WD) / ASUS 8800 GTS512 / 2x NEC-Optiarc AD-7173 / Thermaltake ToughPower 650W / 2x30W Microlab Solo-2 / 20" LCD Benq FP202W (wide) / openSUSE 11.1 / KDE 4.2.1
<!--coloro:Navy--><span style="color:Navy"><!--/coloro-->оН БЯЕЛ БНОПНЯЮЛ - Б email. б ICQ ОНЪБКЪЧЯЭ ПЮГ Б ОНКЦНДЮ.<!--colorc--></span><!--/colorc-->
dAnIK SeNT
Маршал
 
Сообщений: 5101
Зарегистрирован: Чт мар 28, 2002 7:48 pm
Откуда: яяяп
Пункты репутации: 0


Вернуться в Программирование

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

cron