xcrypt
xcrypt

Reputation: 3386

how to declare and define global variables in order to access them from all headers/source files properly

Well, I'm learning C++ and never really learned how to do stuff that is not OO. I'm trying to get a bit more experience coding in C style.

GobalInformation.h

#pragma once

#ifndef GLOBALINFORMATION_H
#define GLOBALINFORMATION_H

#include "MapInformation.h"

namespace gi {
    MapInformation mapInf;
};

#endif

I would like to be able to access gi::mapInf from every header and cpp in my project. Right now I'm including globalinformation.h in every header, so I'm getting linker errors with multiple definitions.

How can I work around the problem?

Upvotes: 20

Views: 28321

Answers (5)

SChepurin
SChepurin

Reputation: 1854

Global variables are C, but namespaces are C++. There is a good discussion on using global variables and how they can be replaced by Singleton pattern: Globals and Singletons

And here is a simple sample: CPP/Classes/Singleton

Upvotes: 3

Gatothgaj
Gatothgaj

Reputation: 1721

Here are a few things that you need to take care of while trying to use global variables the way you have used.

  1. Ensure that all the header files that the header files that GobalInformation.h includes are also enclosed insides #ifndefs. (I could not see mapinformation.h so I assume you have done it)

  2. Just like CPP, C compiler also does not ensure order of the initialization of variables in different translation units(different C/CPP files). Hence declare the header file as

    //GlobalInformation.h
    
    namespace gi {
        extern MapInformation mapInf;
    };
    
  3. In a function that you know would be called first initialize the variable. This way lazy-initialization can also be acheived in C.

Upvotes: 1

mantler
mantler

Reputation: 889

Perhaps a better solution is to create a global object that contains all your global data. Then pass a smart pointer to the classes that actually need to access this shared global data. Example:

class GlobalData
{
public:
    int ticks_;
};   


//Other file
class ThatNeedsGlobalData
{
public:
ThatNeedsGlobalData(std::shared_ptr<GlobalData> globalData);
};

This will save you some trouble.

Good luck!

Upvotes: 2

Kevin Hopps
Kevin Hopps

Reputation: 727

Be aware that having globals in multiple compilation units can easily lead to order-of-initialization problems. You may wish to consider replacing each global with a function that returns a reference. In your case, put this in one cpp file and declare it in the header:

namespace gi {
    MapInformation& getMapInf()
    {
        static MapInformation result;
        return result;
    }
}

Upvotes: 17

parapura rajkumar
parapura rajkumar

Reputation: 24423

In header file only do

namespace gi {
    extern MapInformation mapInf;
};

In CPP file provide the actual definition.

namespace gi {
    MapInformation mapInf;
};

It will work as you intend.

If you are using the MapInformation across dynamic link library boundaries you might have to link against the library that includes the definition cpp file. Also on Window you might have to use dllimport/dllexport

Upvotes: 36

Related Questions