简体   繁体   中英

C++ extern keyword and global variables

I have two files called file_utils.h and file_utils.cpp which contain some methods and variables which are used by different classes. Here's an example of how it looks:

file_utils.h:

namespace my_namespace
{
extern Foo* foo;
extern Bar* bar;

void my_function(Blah* blah);
}

file_utils.cpp

#include "file_utils.h"

void my_namespace::my_function(Blah* blah)
{
    foo = 0;    // undefined reference to my_namespace::foo
    bar = 0;    // undefined reference to my_namespace::bar
    //...
}

some_class.cpp

#include "file_utils.h"

some_function()
{
    my_namespace::my_function(blah);
    this->foo = *my_namespace::foo; // will that work ok?
}

So the errors are in the comments. If I remove the extern keyword I get multiple definition of my_namespace::foo error. What is the problem? Is that even a good idea from design standpoint or should I try to use a class with static members and methods instead?

The problem is that you only declared but not defined the variables.

You need to provide a definition in a single implementation file:

file_utils.cpp

#include "file_utils.h"

//definition:
namespace my_namespace
{
   Foo* foo;
   Bar* bar;
}

//alternatively, to keep the same formatting you have
//Foo* my_namespace::foo;
//Bar* my_namespace::bar;

void my_namespace::my_function(Blah* blah)
{
    foo = 0;
    bar = 0;
    //...
}

To begin with, i would really recommend you to clarify yourself two differences:

  • Declaration vs definition
  • compiler vs linker

In your case you get linker error. Undefined reference means, that your code points somewhere, but the linker is unable to figure out where.

The extern keyword is used to suppress compiler error, when you use an object found somewhere in your code. In your example the linker tries to find instances of your classes but fails. This is not commonly used with pointers (correct me if i'm wrong). Therefore:

utils.h :

namespace mySpace{
    extern Foo foo; // notes that foo of type Foo will be used.

    void myFn();
}

utils.cpp :

#include "utils.h"

void mySpace::myFn(){
    foo.bar = 5; // changes a member of foo from globals.cpp
}

globals.cpp

Foo mySpace::foo; // this is the actual foo used.

If you want your question about some_class.cpp answered please provide the community with knowledge of what is conversions and what you want to achieve.

Judging from semantics I believe it to be a reference to a member of a class conversions .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM