tags:

views:

172

answers:

6

Hi, I want to ensure that my C++ class is never instantiated before main() is entered. Is there any way to achieve this?

--

Some clarification:

I am writing an embedded application. My class must be static (reside in the BSS), but at instantiation it requires some resources that aren't available before certain things has been initialized in start of main(). So I want to make it a Meyers singleton. Ideally I would like to make some kind of assert that ensures that MyClass::instance() is never called before main().

+7  A: 

Restricting construction of a class before some method gets called is going to be a losing battle. Especially if that method is main(). Can I ask why you have this requirement? Perhaps there is another way to tackle the actual problem you're attempting to solve.

Edit: thanks for the CTQ, and judging from it your best bet is probably the simplest solution, which is a static boolean. Since it's embedded I'm going to make the assumption that you pretty much control the entire environment. A simple assert in your ::instance() based on a static bool is probably all that you need.

Taking it one step further, It sounds like you need dependency injection or some other way of assuring that your resources are initialized in the correct order, which I'll be honest, is not a problem I've tackled in C++ (let alone on an embedded system). I can't give any additional insight into the most effective means for that case and would suggest you consider maybe one of the other answers to this question.

sixlettervariables
Well, I am writing an embedded application. My class must be static (reside in the BSS), but at instantiation it requires some resources that aren't available before certain things has been initialized in start of main(). So I want to make it a Meyers singleton.Ideally I would like to make some kind of assert that ensures that MyClass::instance() is never called before main().
kotlinski
A: 

There is no clean way to do this. Perhaps there's something hackish you can do to achieve this end, but you shouldn't.

Describe the fuller need and I'm certain a better solution can be found.

Eli Bendersky
+2  A: 

Give your class a static bool that is set on the first instantiation, and check it at the beginning of main()

Using a factory or making the constructor private will not stop it being instantiated in the constructor of a class that is instantiated before main()

David Sykes
A: 

One possible way is to instance the class inside main. i.e.

MyClass * g_thing = 0;
int main()
{
    g_thing = new MyClass();
}

Other than that it's a tricky, compiler specific mess. What are you trying to achieve?

James Brooks
This really has nothing to do with the question asked.
shoosh
+1 right on target
EvilTeach
It is an alternative way to achieve what he wants which overcomes the problem in question (while adding other limitations; but nothing is perfect). I should have explained myself better but I don't think it has *nothing* to do with the question.
James Brooks
Since the clarification has been added my question is off topic.
James Brooks
A: 

If you can control the code that gets executed when main() starts, then you can have a function like this:

bool wasMain (bool inMain = false) {
  static bool passedMain = false;
  return passedMain |= inMain;
}

Then, first line within main use wasMain(true) and it shall return true from there onwards, whereas it will return false until that point.

Edit: I just love shorter code, the above implementation can be simplified to:

bool wasMain (bool inMain = false) {
  static bool passedMain = false;
  if (inMain)
    passedMain = true;
  return passedMain;
}
rmn
+2  A: 

One thing you can do is have a static method like MyClass::enableConstruction() which turns on a static flag in the class. If the c'tor is called when this flag is false then it throws an exception. This way you'll alteast have some run-time indication that someone is breaking the rules.

Notice that you should be careful with the initialization of that static flag. To avoid any construction order problems it would probably be best to make it a singleton that is initialized when first accessed.

shoosh