this is my first question on stack overflow, so be gentle.
Let me first explain the exact behavior I would like to see. If you are familiar with C# then you know that declaring a variable as "readonly" allows a programmer to assign some value to that variable exactly once. Further attempts to modify the variable will result in an error.
What I am after: I want to make sure that any and all single-ton classes I define can be predictably instantiated exactly once in my program (more details at the bottom).
My approach to realizing my goal is to use extern to declare a global reference to the single-ton (which I will later instantiate at a time I choose. What I have sort of looks like this,
namespace Global
{
extern Singleton& mainInstance; // not defined yet, but it will be later!
}
int main()
{
// now that the program has started, go ahead and create the singleton object
Singleton& Global::mainInstance = Singleton::GetInstance(); // invalid use of qualified name
Global::mainInstance = Singleton::GetInstance(); // doesn't work either :(
}
class Singleton
{
/* Some details ommited */
public:
Singleton& GetInstance()
{
static Singleton instance; // exists once for the whole program
return instance;
}
}
However this does not really work, and I don't know where to go from here.
Some details about what I'm up against:
I'm concerned about threading as I am working on code that will deal with game logic while communicating with several third-party processes and other processes I will create. Eventually I would have to implement some kind of synchronization so multiple threads could access the information in the Singleton class without worry. Because I don't know what kinds of optimizations I might like to do, or exactly what threading entails (never done a real project using it), I was thinking that being able to predictably control when Singletons were instantiated would be a Good Thing.
Imagine if Process A creates Process B, where B contains several Singletons distributed against multiple files and/or libraries. It could be a real nightmare if I can not reliably ensure the order these singleton objects are instantiated (because they could depend on each other, and calling methods on a NULL object is generally a Bad Thing).
If I were in C# I would just use the readonly keyword, but is there any way I can implement this (compiler supported) behavior in C++? Is this even a good idea? Thanks for any feedback.
Edit
If I was locked in to following the code example above, the selected answer would be the easiest way to do what I needed. I decided to change the pattern away from singleton though, even though I only plan to ever make one of these EntryPoint objects.
class EntryPoint
{
/* Intentionally defined this way to discourage creation */
EntryPoint(const EntryPoint &); // undefined & private
EntryPoint& operator=(const EntryPoint &); // undefined & private
// public
EntryPoi开发者_运维问答nt()
{
/* All of the action is performed here! */
}
/* Other supporting functions */
}
// The easier to understand main function!
int main()
{
EntryPoint * ep = new EntryPoint(); // transfer control to the entrypoint
delete ep;
}
One of the reasons I was thinking I would need all these singletons is I plan to create a larger architecture that would support modular plugin-type applications. I also wanted more error-checking and memory protection to minimize memory leaks. I was happy to find that the cross-platform Qt (http://qt.nokia.com/) offers a guarded pointer and other cool features.
Why not just use Singleton::GetInstance
directly? Why do you need to store it in a (readonly) global? This solves dependency issues as well.
Only allow access by calling:
Singleton::GetInstance
Enforce this by making your copy and assignment constructors private
private:
Singleton(){}
Singleton(Singleton const&){}; //copy ctor private
Singleton& operator=(Singleton const&){};
精彩评论