Defining structs globally in C ++

there was a somewhat detailed thread (228684) on how globally (using extern struct) declares a structure that can be seen in more than one C ++ file, but I can't figure out exactly how to do it (there was a lot of discussion about this, do this, maybe do this, try this, etc.).

buy someone please write a very simple example of how to declare a structure that can be seen in two separate C ++ files? If I put all my functions in the same file as the main one, it works fine, but when I try to split the functions in different files, I can't compile it.

Things I don't understand ... Should I print the structure? Am I defining the structure in a header file and include that header in every C ++ source file? Do I need macro C # ifndef in the header file? Am I declaring an extern structure in the header?

thank

+1


source to share


4 answers


It is called a header file.

in your header file (call it foo.h)

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

      



Then in any C files you have

#include "foo.h"
X x;

      

For C ++ it is more common / preferred to use a class, but you can also use a struct. The extern keyword usually refers to variables, not class / struct declarations. You have to make a global extern variable in the header file (then declare it non-extern) in one of your .cpp files.

+7


source


Structures cannot be external or static. If you want to have a structure used in more than two translation units, put the structure definition in the header:

foo.hpp

struct foo {
    int a;
    int b;
};

      

Then include this header file in all source files using this structure. Having a structure / class / union defined in multiple source files is perfectly fair if each is defined the same. You can put Enable Guard around the definition foo

to prevent foo from being included in the same source file that was compiled. (So ​​having multiple foo

in one program is valid, but having multiple foo

in one source (note: translation unit means) is not valid.) See 3.2 One rule of definition in the C ++ standard or Draft .



When you see this:

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

      

Not foo

extern, but b

(object) is extern! It says it is b

not defined, but simply declared, so you can reference it.

+3


source


If you want a global variable; one structure available from multiple compilation units (C ++ files):

/* 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
}

      

The line "struct {}" in foo.h tells the compiler what the structure foo looks like. The "extern struct" line declares a specific foo structure called "globalFoo" with an external link. (It is possible to combine the two, see @litb's answer.) This means that users of globalFoo (bar1 / test1 and bar2 / test2) will look elsewhere for the structure, they will not have separate copies of their own.

foo.cpp is a special case defining globalFoo. There can only be one definition of any variable, in which case foo.cpp has the definition of globalFoo. When bar1 and bar2 look for globalFoo "from the outside", they find foo.cpp globalFoo. The name will refer to the same actual structure in all three files.

If extern

it was not there, all three .cpp files would have a line that reads "struct foo globalFoo;" (Remember, #include is just copy / paste). It would [try] to create three different structures with the same name, which would lead to a mess.

Note. The string " extern struct foo globalFoo;

" is redundant in the case of foo.cpp, but it doesn't matter.

+1


source


Here's a small example:

#ifndef __my_header__
#define __my_header__

class my_class
{

};

#endif

      

The class my_class

will be visible in any file that includes this header. I think there is more to your question, but I don't quite understand what.

0


source