Заголовки Visual Studio C ++ - PullRequest
       9

Заголовки Visual Studio C ++

0 голосов
/ 15 июля 2011

Мне нужно создать такую ​​структуру:

// file main.h:
#pragma once

#ifndef _MAIN_H
#define _MAIN_H

#include <iostream>

#include "first.h"
#include "second.h"

#endif
// -----------------

// file first.h:
#pragma once

#ifndef _FIRST_H
#define _FIRST_H

#include "main.h" // because of using SomeFunction() in first.cpp

int SomeVar; // used in first.cpp

#endif
// -----------------

// file second.h:
#pragma once

#ifndef _SECOND_H
#define _SECOND_H

#include "main.h" // because of using SomeVar in second.cpp

int SomeFunction(); // implemented in second.cpp

#endif
// -----------------

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

Например, эта конфигурация обычно компилируется в компиляторе IAR C ++, если для параметров «preinclude file» (not precompiled) задано main.h.

Но в Visual Studio 2010 такая же структура вызывает ошибки компоновщика, такие как:

1>second.obj : error LNK2005: "int SomeVar" (?SomeVar@@3HA) already defined in first.obj
1>second.obj : error LNK2005: "int SomeFunction" (?SomeFunction@@3HA) already defined in first.obj

Я думаю, из-за включения файлов в алфавитном порядке. По-видимому, компоновщик игнорирует pragma- и define-guards.

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

Вопрос: что мне делать?

Ответы [ 2 ]

2 голосов
/ 15 июля 2011
int SomeVar; // used in first.cpp

Переменные никогда не должны определяться в заголовках. Они должны быть объявлены с extern:

extern int SomeVar; // used in first.cpp

Затем вы можете определить их в "first.cpp" с помощью int SomeVar;.


Кроме того, «first.h» не нужно для включения «main.h». Заголовки должны только включать файлы, если определения в этом заголовке абсолютно нуждаются в содержимом этих файлов. Определения в "first.h" ничего не нужно в "main.h". Следовательно, оно не должно включать его.

Если «first.cpp» должен включать что-то из «second.h», то «first.cpp» обязан включить его.

1 голос
/ 15 июля 2011

В заголовочном файле используйте ключевое слово extern как:

//first.h
extern int SomeVar; //extern tells the compiler that definition is elsewhere

Затем в файле .cpp определите его и используйте:

//first.cpp
int SomeVar; //definition is here

Что касается SomeFunction, вы сами определили заголовочный файл?Перепроверьте это.: -)

...