Going to all the effort of making a singleton object using the usual pattern isn't addressing the second part of your question - the ability to make more if needed. The singleton "pattern" is very restrictive and isn't anything more than a global variable by another name.

// myclass.h

class MyClass {
public:
    MyClass();
    void foo();
    // ...
};

extern MyClass g_MyClassInstance;

// myclass.cpp

MyClass g_MyClassInstance;

MyClass::MyClass()
{
    // ...
}

Now, in any other module just include myclass.h and use g_MyClassInstance as usual. If you need to make more, there is a constructor ready for you to call.

Answer from Greg Hewgill on Stack Overflow
Top answer
1 of 3
3

It is just a static object. It is treated like any other global variable.

It will not be tied to any stack frames and will be created when the anything in the file is loaded for the first time.

Generally, people will not recommend relying on globals from a design perspective. It depends though, they can be reasonable.

If you are doing any sort of threading they can be an issue. You also want to minimize different parts of your application knowing that things are global variables, it leads to a lot of spaghetti code.

If the variable is not referenced outside of the file, or for cross-cutting concerns, then sometimes it can be a good thing.

The best advice is to avoid it when you can, don't over design it when you can't.

2 of 3
1

Objects that are global variables (or more precisely variables "at namespace scope") have static storage duration. This means they live until the end of the program, and they are initialized during program startup (either during the static or the dynamic initialization phase).

The order of initialization is not generally specified except that all such global objects are initialized before main() is called, and that the initialization does not introduce data races.

(Common techniques to sequence mutually dependent global initialization is to replace naked global variables with a global getter function and a block-static variable:

Foo & getFoo() { static Foo impl; return impl; }

Now any other global using getFoo() in its own constructor will be initialized after impl.)

Discussions

Global Class Objects? - C++ Forum
Right now i have my object declared as so: Engine engine; How would i make "engine" global so that i could use it within other classes in different source files? ... By declaring it in a header as: extern Engine engine; When there should be at most one instance of that class, the singleton ... More on cplusplus.com
🌐 cplusplus.com
July 20, 2011
How to create a global object/instance o - C++ Forum
Hi, I'm new in object oriented programming. I need help creating a global object/instance of a class, that can be used by any function. Does anyone knows a solution? More on cplusplus.com
🌐 cplusplus.com
C++: Declare a global class and access it from other classes? - Stack Overflow
Just use a global and ditch all the single-instance crap you don't need. 2010-05-09T21:24:08.707Z+00:00 ... There actually is one very good reason to use Singleton: You don't have to remember to extern the class in every single file you want to use it from. Could lead to weird errors, probably not. More on stackoverflow.com
🌐 stackoverflow.com
Global Class - C++ Forum
Class member function definitions are implicitly inline, so they can be placed in header files without any issue. Global instances, as global variables, need to be declared extern every place they're used and defined in only one TU. More on cplusplus.com
🌐 cplusplus.com
🌐
DaniWeb
daniweb.com › programming › software-development › threads › 452289 › global-class-instance
c++ - global class instance [SOLVED] | DaniWeb
April 12, 2013 - The problem arises because the class instance needs to be instantiated after other data is made available globally after another non class function has logged into website, and returned configuration data.
🌐
Cplusplus
cplusplus.com › forum › beginner › 47143
Global Class Objects? - C++ Forum
July 20, 2011 - Right now i have my object declared as so: Engine engine; How would i make "engine" global so that i could use it within other classes in different source files? ... By declaring it in a header as: extern Engine engine; When there should be at most one instance of that class, the singleton pattern is often used.
🌐
Cplusplus
cplusplus.com › forum › general › 109265
How to create a global object/instance o - C++ Forum
If the global can be used from any function, be sure that the functions: a) Cannot be used at the same time OR b) Each function tries to lock a mutex so other functions will fail on attempt, thus not resulting in a race condition. ... Pacman is an incomplete type because you didn't use curly braces to define it. ... There are certain things you cannot do without the full definition of the class.
🌐
Cplusplus
cplusplus.com › forum › beginner › 206333
Global Class - C++ Forum
Class member function definitions are implicitly inline, so they can be placed in header files without any issue. Global instances, as global variables, need to be declared extern every place they're used and defined in only one TU.
🌐
Quora
quora.com › Considering-C-are-the-global-variables-the-same-as-instance-variables-If-not-what-are-their-differences
Considering C++, are the global variables the same as instance variables? If not, what are their differences? - Quora
From the view of program design, instance variables are “owned” and possibly “hidden” from the global namespace, and cannot be directly accessed from anywhere. Global variables are at the top level namespace and any part of the program can...
Find elsewhere
🌐
Reddit
reddit.com › r/cpp_questions › how do i make a class instance global?
How do I make a class instance Global? : r/cpp_questions
September 25, 2024 - This works, but when you start working on larger projects, where various global classes might depend on each other, you will run into problems eventually (static initialization order issues). You could look into the Singleton design pattern as a more robust alternative. ... You could look into the Singleton design pattern as a more robust alternative. depends on how many instances are needed.
Top answer
1 of 4
3

Using an extern variable is one option.

Another option is to have a function that returns a reference.

logging.h:

LogCenter& getGlobalLogCenter();

logging.cpp:

LogCenter& getGlobalLogCenter()
{
   static LogCenter lc;
   return lc;
}
2 of 4
2
//logcenter.h
#ifndef LOGCENTER_H_
#define LOGCENTER_H_

class LogCenter {
private:
    int dummy;
public:
    int getVal(){ return dummy; };
    LogCenter() : dummy(0){};
    LogCenter(int val) : dummy(val) {};
};

#endif  // LOGCENTER_H_

xxx

// logcenter.cpp
#include "LogCenter.h"

LogCenter globalCenter;

xxx

//logger.h
#ifndef LOGGER_H_
#define LOGGER_H_

#include <string>
#include "LogCenter.h"

class Logger {
private:
  LogCenter& center;
public:
  Logger();  //automatically assigns the ominous global LogCenter object (reference) to center.
  Logger(LogCenter&);  //however, any other LogCenter object would work equally fine.
  std::string print() { return std::string("This class uses logger ") + std::to_string(center.getVal()); };
};

#endif // LOGCENTER_H

xxx

// logger.cpp
#include "Logger.h"

extern LogCenter globalCenter;

Logger::Logger() : center(globalCenter) {};

Logger::Logger(LogCenter &logcenter) : center(logcenter) {};

xxx

// main.cpp
#include "Logger.h"

int main(int argc, char* argv[])
{
    LogCenter logcenter2(2), logcenter3(3);
    Logger logger1, logger2(logcenter2), logger3(logcenter3);

    std::cout << logger1.print() << std::endl;
    std::cout << logger2.print() << std::endl;
    std::cout << logger3.print() << std::endl;

    return 0;
}

output is:

This class uses logger 0
This class uses logger 2
This class uses logger 3
🌐
NeoGAF
neogaf.com › discussions › off-topic discussion
c++ global class instance? scope am fail :( | NeoGAF
November 23, 2009 - Unless you think you might accidentally instantiate two (think about it...it's a mistake you probably would never make) and that instantiating more than one would cause problems (in most case, it won't, and users of your class might WANT to instantiate more than on in some cases) then there's no need for a singleton imo. ... Do this, but with references instead of pointers. If you must use a global, you can, if you wish, place an extern declaration in the header file for your scene manager: extern SceneManager g_SceneManager; That way, any source file (cpp) that includes this header will have access to the global.
🌐
MIT
web.mit.edu › tibbetts › Public › inside-c › www › initializing-globals.html
The Secret Life of C++: Initializing Globals
Basically, global constructors and destructors get "registered" and called at program start and shutdown, using the _init and _fini sections of the executable.
🌐
SourceForge
libcw.sourceforge.net › global › global.html
Global Objects Management
The CONVERTER class converts the given instance integer into data of an arbitrary type that is passed to the constructor of TYPE when the object is created. Constructors of static, global and Global<> classes need to access such objects through the member function Global<TYPE, instance, CONVERTER>::instantiate(), while other code can access the object without a check for instantiation through a call to the member function Global<TYPE, instance>::instance().
🌐
Inductive Automation
forum.inductiveautomation.com › general discussion
"Global" Instance of a Class - General Discussion - Inductive Automation Forum
August 11, 2015 - Hi all, In Ignition, is there any way to create a “global” instance of a class in Ignition when a client/project is started up? Suppose we have (GUI) Button A and Button B and both have scripts for “actionPerformed”. In both scripts, suppose there is an instance inst_foo of a class foo used.
🌐
Cprogramming
cboard.cprogramming.com › cplusplus-programming › 70249-static-class-variable-vs-global-variable.html
static class variable vs. global variable - C Board
Years ago when cpu speeds were very slooooow that was a very big deal, so we used globals to eliminate that slowdown in time-critical applications. Today, when lightning-fast cpus there is almost no difference, but the difference is there nonetheless. The difference between non-c++ class static variable and a static variable of a class is scope.
Top answer
1 of 4
15

Your doubt is correct, don't use global variables.

(Note: For this post, I mean variable in its true meaning, i.e. objects that may change.)

I can't say for sure which technique is the correct one without seeing your code, but normally you want to pass the variable as a parameter to whichever entity needs it:

void foo(Input input)
{
    input.doSomething();
}

int main()
{
    Input input;
    input.doSomething();

    foo(input);
}

Or, restrict it to a class as a member variable.


Update: Class examples

You can do it one or both of these ways:

class Person {
    std::string name_;
public:
    explicit Person(std::string const& name) : name_(name) {}
    void set_name(std::string const& name) { name_ = name; }
}

void foo()
{
    Person p("Bob Loblaw");

    p.set_name("Slartibartfast");
}

There are two key downsides to using global variables:

1. They can be changed everywhere.

You generally want to enlist the compiler's aid in finding bugs and errors for you. If you allow yourself to modify a variable from all over your code, it is very hard for your compiler and yourself to track down an error. Consider the following scenario:

Input input; // global

void foo()
{
    Input inputt;
    input = someThingWeird;
}

This code will compile. If you're really unlucky, it will even work for a while. If you don't have a global, the code won't compile and the bug will be easy to find.

2. They increase coupling (and reduce testability).

By reading from a global variable, your entity (i.e. function, class, whatever) depends on that global variable. If some day you want to use something else, you'll have to do a lot of refactoring. What's more important, if you change an aspect of the global variable, you will need to update all parts of the code that uses it. This is a great opportunity for suble bugs to infiltrate your code and make your life miserable. A typical example is that you modify one part of your code, and a completely different part will break.

Using globals also makes your code hard to unit test, because it depends on the global variable.

2 of 4
7

@Lstor is absolutely correct. However, I'll like to add some things:

  • If you're using constants (indicated by the const keyword), they're okay as globals. This is because they cannot be changed elsewhere in the code, unlike global variables).

  • I'd recommend classes, especially when writing a game. When used properly, they will allow you to hide your data from entities that should not have access to them. However, it's best not to use them just to avoid globals, especially when they can still be passed around. They should serve some kind of role, even if your program doesn't revolve around classes. In your case, you'll most likely have a Game class and possibly additional classes. More general info about this here.

🌐
Particle
docs.particle.io › reference › device-os › api › global-object-constructors › global-object-constructors
Global object constructors | Reference | Particle
It can be convenient to use C++ objects as global variables. You must be careful about what you do in the constructor, however. The first code example is the bad example, don't do this. #include "Particle.h" SerialLogHandler logHandler; class MyClass { public: MyClass(); virtual ~MyClass(); void subscriptionHandler(const char *eventName, const char *data); }; MyClass::MyClass() { // This is generally a bad idea.