If the constructor throws an exception, does it make sense to have a global object of this class?

I ask this question for general coding rules:

class A { A() { ... throw 0; } }; A obj; // <---global int main() { } 

If obj throws an exception in the above code, then it will end the code before calling main() . So my question is: what guidance should I take for such a scenario? Is it possible to declare global objects for such classes or not? Should I always refrain from this, or is it a good tendency to catch a mistake at the very beginning?

+8
c ++ coding-style exception global-variables
source share
6 answers

If you need a global instance of an object whose constructor can call, you can make the variable static, instead:

 A * f(){ try { //lock(mutex); -> as Praetorian points out static A a; //unlock(mutex); return &a; } catch (...){ return NULL; } } int main() { A * a = f(); //f() can be called whenever you need to access the global } 

This will alleviate the problem caused by premature exception.

EDIT: Of course, in this case, the solution is 90% of the path to Singleton. Why not just completely turn it into one by moving f() to A ?

+4
source share

No, you should not declare such objects global - any exception will be unhandled and very difficult to diagnose. The program will simply crash, which means that it will have a very bad (below zero) user interface and it will be quite difficult to maintain.

+1
source share

As @Kerrek SB noted in the comments, the answer to this question depends on the reasons that might cause your class to throw. If you are trying to acquire a system resource that may not be available, I feel that you should not declare a global object. Your program will work as soon as the user tries to start it; Needless to say, this does not look very good. If it can throw std::bad_alloc or some kind of exception that is unlikely under normal circumstances (provided that you are not trying to allocate several GB of memory), you can create a global instance; however, I didn’t do it anyway.

Instead, you can declare a global pointer to an object, create an instance of the object at the beginning of main (before threads are created, etc.) and point to that instance, then access it through a pointer. This gives your program the opportunity handle exceptions and, perhaps, offers the user to take some measures to correct the situation (for example, pull out the redo button to try to restore the resource, for example).

0
source share

The announcement of the global object is beautiful, but the design of your class is insignificant, it lacks details so that they are compatible with practical needs and use.

0
source share

One solution that no one seems to have mentioned is to use the try block function. Basically, if the situation is such that without the constructed object, the rest of your program will not work or cannot do anything useful, then the only real problem is that your user will receive some kind of incomprehensible error message if the constructor ends with an exception . Thus, you end the constructor in the try try block of the function and generate a clear message, followed by the error message:

 A::() try : var1( initVar1 ) // ... { // Additional initialization code... } catch ( std::exception const& ) { std::cerr << "..." << std::endl; exit(EXIT_FAILURE); } catch (...) { std::cerr << "Unknown error initializing A" << std::endl; exit(EXIT_FAILURE); } 

This solution is really applicable, however, if all instances of the object are declared statically or if you can allocate one constructor for static instances; for non-static instances, it is probably best to throw an exception.

0
source share

As @JT said, you can write like this:

 struct S { S() noexcept(false); }; S &globalS() { try { static S s; return s; } catch (...) { // Handle error, perhaps by logging it and gracefully terminating the application. } // Unreachable. } 

Such a scenario is quite a challenge, please read ERR58-CPP. Handle all exceptions that were thrown before main () starts execution for more details.

0
source share

All Articles