2008-11-25 2 views
1

был несколько подробный поток (228684) о том, как глобально (используя extern struct) объявляет структуру, которая может быть замечена в более чем одном файле C++, но я не могу точно определить, как это сделать это (было много разговоров об этом, сделайте это, возможно, сделайте это, попробуйте это и т. д.).определение структур глобально в C++

купил кого-то, пожалуйста, напишите очень простой пример того, как объявить структуру, которая может быть видна в двух отдельных файлах C++? Если я поместил все свои функции в тот же файл, что и основной, он работает нормально, но когда я пытаюсь разделить функции в разных файлах, я не могу его скомпилировать.

Вещи, которые я не понимаю ... Должен ли я напечатать структуру? Я определяю структуру в файле заголовка и включаю этот заголовок в каждый исходный файл C++? Нужен ли мне макрос #ifndef в файле заголовка? Я объявляю структуру extern в заголовке?

Спасибо

ответ

7

Это называется заголовочным файлом.

в файле заголовок (назову его foo.h)

#ifndef FOO_H 
#define FOO_H 
class X { 
}; 
#endif 

Затем в любых файлах C у вас есть

#include "foo.h" 
X x; 

Для C++ это более общее/предпочтительно использовать класс, но вы может также использовать структуру. Ключевое слово extern обычно относится к переменным, а не к объявлениям class/struct. Вы бы сделали глобальную переменную extern в файле заголовка (тогда объявите его не-extern) в одном из ваших .cpp-файлов.

+0

#ifndef, #define и #endif предназначены для защиты вас от довольно распространенного случая, когда вы случайно включаете один и тот же файл дважды (обычно через какой-то третий файл) – 2008-11-25 19:32:46

+0

Я закодировал немного C, чтобы ознакомиться с указатели и т. д., поэтому я могу с уверенностью сказать, что мое незнание на C++ является абсолютным. Однако, что всегда меня беспокоило: было бы так сложно компилятору проверить, был ли файл уже включен, и в этом случае не включать его снова? – 2008-11-25 23:55:47

0

Вот небольшой пример:

#ifndef __my_header__ 
#define __my_header__ 

class my_class 
{ 

}; 

#endif 

Класс my_class будет виден в любом файле, который включает этот заголовок. Я думаю, что есть еще кое-что на ваш вопрос, но я не совсем понимаю, что.

3

Структуры не могут быть внешними или статическими. Если вы хотите, чтобы иметь структуру, используемую в более чем двух единиц перевода, поместить определение структуры в заголовок:

foo.hpp

struct foo { 
    int a; 
    int b; 
}; 

Затем включить этот заголовочный файл во все исходные файлы, используя которые структура. Наличие структуры/класса/объединения, определенных в нескольких исходных файлах, совершенно справедливо, если каждый из них задан одинаковым. Вы можете поместить Include Guard вокруг определения foo, чтобы предотвратить включение foo в один и тот же исходный файл, который был скомпилирован. (Таким образом, наличие нескольких foo в той же программе действительно, но наличие нескольких foo в том же источнике (примечание: единица перевода значения) недопустимо.) См. 3.2 Одно правило определения в стандарте C++ или Draft.

Когда вы видите это:

extern struct foo { int a; int b; } b; 

Не foo является ехЬегп, но b (объект) является ехЬегп! Он говорит, что b не определен, а просто объявлен, поэтому вы можете ссылаться на него.

1

Если вы хотите глобальную переменную; а одиночные Struct доступны из нескольких единиц компиляции (файлы C++):

/* foo.h */ 
#ifndef EXAMPLE_FOO_H 
#define EXAMPLE_FOO_H 

struct foo { 
    int a; 
    int b; 
}; 

extern struct foo globalFoo; 

#endif /* EXAMPLE_FOO_H */ 

-

/* foo.cpp */ 
#include "foo.h" 

struct foo globalFoo = { 1, 2 }; 

-

/* bar1.cpp */ 
#include "foo.h" 

int test1() 
{ 
    int c = globalFoo.b; //c is 2 
} 

-

/* bar2.cpp */ 
#include "foo.h" 

int test2() 
{ 
    int x = globalFoo.a; //x is 1 
} 

«структура {} "строка в foo.h сообщает компилятору, что st ruct foo выглядит как. Строка «extern struct» объявляет конкретную структуру foo, называемую «globalFoo», с внешней связью. (Можно объединить эти два объявления, см. Ответ @ litb.) Это означает, что пользователи globalFoo (bar1/test1 и bar2/test2) будут искать структуру в другом месте, у них не будет собственных отдельных копий.

foo.cpp - специальный случай, определяющий globalFoo. Может быть только одно определение любой переменной, и в этом случае foo.cpp имеет определение globalFoo. Когда bar1 и bar2 ищут globalFoo «извне», они найдут foo.cpp's globalFoo. Имя будет ссылаться на одну и ту же фактическую структуру во всех трех файлах.

Если extern не был там, все три файла .cpp имели бы строку, которая читает «struct foo globalFoo;». (Помните, что #include - это просто копировать/вставлять). Было бы [пытаться] создать три разные структуры с тем же именем, что приведет к беспорядку.

Примечание: Линия «extern struct foo globalFoo;» избыточна в случае foo.cpp, но это не имеет значения.

Смежные вопросы