简体   繁体   中英

C++ extern pointer

So I'm writing a program which has a big class called oglapp, and a whole bunch of other classes using it. What I want to achieve is to have a super-global oglapp* across all my .cpps. My approach is to declare an oglapp* in the main.cpp, which has the entry point (which sets up the pointer and starts running the class), and I have an extern reference at the end of the header file of oglapp. In theory, if I use the oglapp class anywhere in my project I need to include the header for it, which includes the extern, and I'm good. This is sorta what I have:

//main.cpp
oglapp* app;
entrypoint(){app=new oglapp(); app->run();}

//oglapp.h
class oglapp { ... }; extern oglapp* app;

//classX.h
#include "oglapp.h"
classX { ... };

//classX.cpp
#include "classX.h"
void classX::somefunction(){app->dosomething();}

What I get is a big null reference error. I tried including the oglapp header from the .cpp of classX, also tried putting the extern oglapp* app; to each of the classXs individually, I tried everything I could think of. Also, weirdly enough, I don't get null reference errors in all the classXs. Some of them can use the app without a problem, some of them see it as a null pointer. I've yet to discover what determines if it's working or not.

What am I doing wrong? Also, if it's impossible to declare a single super-global pointer to a class this way, how should I go about doing it?

It'll work reliably for anything that is instantiated from within main or anything that main invokes. For objects at global scope, those are constructed before main is run, so your pointer won't be set yet.

You can make everything get initialised from within main or higher up the call stack, or you can make an oglapp singleton.

Or, since it doesn't look like oglapp takes any arguments to its constructor, you can extern an actual instance and create one of those at global scope, rather than a pointer. Then you have to be wary of the static initialisation order fiasco (look it up!), but at least your other global objects will have a chance … if you're careful.

It's difficult to see where the problem is since you haven't posted all of your code. However, you can avoid the null reference problem by making oglapp a singleton. See http://en.wikipedia.org/wiki/Singleton_pattern for details.

"Singeton" seems the most-logical answer here to me. And it's easy to do. You simply declare a function that returns an instance of oglapp ... creating it the first time, returning it thereafter. Something like:

static *oglapp _instance = NULL;
*oglapp oglapp_factory() 
{
   if (_instance == NULL) _instance = new oglapp();
   return _instance;
}

Your "extern" file declares both the class-definition and (the external existence of ...) "oglapp_factory()." Any routine that needs to interact with the (one and only) instance of the class, calls the factory routine to get it.

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