глобальное определение структур в с ++ - PullRequest
1 голос
/ 25 ноября 2008

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

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

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

Ответы [ 4 ]

7 голосов
/ 25 ноября 2008

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

в вашем заголовочном файле (назовите его foo.h)

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

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

#include "foo.h"
X x;

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

3 голосов
/ 25 ноября 2008

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

foo.hpp

struct foo {
    int a;
    int b;
};

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

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

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

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

1 голос
/ 26 ноября 2008

Если вы хотите глобальную переменную; одна структура, доступная из нескольких модулей компиляции (файлы 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
}

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

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

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

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

0 голосов
/ 25 ноября 2008

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

#ifndef __my_header__
#define __my_header__

class my_class
{

};

#endif

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

...