Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Общие вопросы _ multiple definitions

Автор: void* 22.4.2010, 21:37

Всем привет. Есть один маленький проектик, при компиляции которого Qt Creator ругается на то что одни и те же функции объявляются несколько раз. Скорее всего это из-за множественного включения одних и тех же файлов, но как этого избежать и из-за чего именно это не понимаю). Структура такая(инклюдов):

defines.h

#ifndef DEFINES_H
#define DEFINES_H
//...
#endif // DEFINES_H

calculations.h

#ifndef CALCULATIONS_H
#define CALCULATIONS_H
#include "defines.h"
//...
#endif // CALCULATIONS_H

iterationsdialog.h

#ifndef ITERATIONSDIALOG_H
#define ITERATIONSDIALOG_H
#include "calculations.h"
//...
#endif // ITERATIONSDIALOG_H

iterationsdialog.cpp

#include "iterationsdialog.h"
#include "iterationtable.h"
//...

iterationtable.h

#ifndef ITERATIONTABLE_H
#define ITERATIONTABLE_H
#include "calculations.h"
//...
#endif // ITERATIONTABLE_H

iterationtable.cpp

#include "iterationtable.h"
//...

Ну и в файлах MainWindow уже подключается iterationsdialog.h и используется. Так вот проблема собственно в том, что все функции, описанные в calculations.h почему-то описываются несколько раз, на что и ругается компилятор... как это исправить?

Автор: DEADHUNT 22.4.2010, 21:41

Цитата(void* @ 22.4.2010, 22:37) *
Так вот проблема собственно в том, что все функции, описанные в calculations.h почему-то описываются несколько раз, на что и ругается компилятор... как это исправить?

так у тебя в *.h function declaration или function definition? если первое то ошибок быть не должно.

Автор: void* 22.4.2010, 22:23

сразу полная реализация функций
и компилятор ругается на каждую функцию типа multiple definition и в конце error: collect2: ld returned 1 exit status

Автор: Litkevich Yuriy 23.4.2010, 0:07

Цитата(void* @ 23.4.2010, 2:23) *
сразу полная реализация функций
в этом-то и проблема. Си не паскаль. Разноси объявление в h, реализацию в cpp
А чтоб понять почему так:
возьми cpp и мысленно воткни на место директивы препроцессора целиком соответствующий файл.
Т.е. на место #include "filename", воткни сам файл с именем filename

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

Цитата(void* @ 23.4.2010, 2:23) *
и компилятор ругается
Цитата(void* @ 23.4.2010, 2:23) *
error: collect2: ld returned 1 exit status
заметь, ругается не компилятор

Автор: void* 23.4.2010, 9:32

да, спасибо, я то понимал что не компилятор ругается, но уже давненько не писал и забыл кое-какие нюансы)

Автор: frg10 27.4.2010, 16:16

Всякие мелкие функции можно писать полностью в заголовочных файлах, но нужно делать их inline - тогда линкер ругаться не будет. НО! это приводит к разбуханию кода, т.к. вместо вызова функции может вставиться её тело целиком (это решает компилятор).
П.С. Кстати, впомните, что весь STL в заголовочных файлах лежит.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)