I have read multiple articles about why singletons are bad.
I know it has few uses like logging but what about initalizing and deinitializing.
Are there any problems doing that?
I have a scripting engine that I need to bind on startup to a library.
Libraries don't have main() so what should I use?
Regular functions or a Singleton.
Can this object be copied somehow:
class
{
public:
static void initialize();
static void deinitialize();
} bootstrap;
If not why do people hide the copy ctor, assignment operator and the ctor?
Libraries in C++ have a much simpler way to perform initialization and cleanup. It's the exact same way you'd do it for anything else. RAII.
Wrap everything that needs to be initialized in a class, and perform its initialization in the constructor. Voila, problems solved.
All the usual problems with singletons still apply:
You are going to need more than one instance, even if you hadn't planned for it. If nothing else, you'll want it when unit-testing. Each test should initialize the library from scratch so that it runs in a clean environment. That's hard to do with a singleton approach.
You're screwed as soon as these singletons start referencing each others. Because the actual initialization order isn't visible, you quickly end up with a bunch of circular references resulting in accessing uninitialized singletons or stack overflows or deadlocks or other fun errors which could have been caught at compile-time if you hadn't been obsessed with making everything global.
Multithreading. It's usually a bad idea to force all threads to share the same instance of a class, becaus it forces that class to lock and synchronize everything, which costs a lot of performance, and may lead to deadlocks.
Spaghetti code. You're hiding your code's dependencies every time you use a singleton or a global. It is no longer clear which objects a function depends on, because not all of them are visible as parameters. And because you don't need to add them as parameters, you easily end up adding far more dependencies than necessary. Which is why singletons are almost impossible to remove once you have them.
A singleton's purpose is to have only ONE instance of a certain class in your system.
The C'tor, D'tor and CC'tor are hidden, in order to have a single access point for receiving the only existing instance.
Usually the instance is static (could be allocated on the heap too) and private, and there's a static method (usually called GetInstance) which returns a reference to this instance.
The question you should ask yourself when deciding whether to have a singleton is : Do I really need to enforce having one object of this class?
There's also the inheritance problem - it can make things complicated if you are planning to inherit from a singleton.
Another problem is How to kill a singleton (the web is filled with articles about this issue)
In some cases it's better to have your private data held statically rather than having a singleton, all depends on the domain.
Note though, that if you're multi-threaded, static variables can give you a pain in the XXX...
So you should analyse your problem carefully before deciding on the design pattern you're going to use...
In your case, I don't think you need a singleton because you want the libraries to be initialized at the beginning, but it has nothing to do with enforcing having only one instance of your class. You could just hold a static flag (static bool Initialized) if all you want is to ensure initializing it only once.
Calling a method once is not reason enough to have a singleton.
It's a good practice to provide an interface for your libraries so that multiple modules (or threads) can use them simultaneously. If you really need to run some code when modules are loaded then use singletons to init parts that must be init once.
count the number of singletons in your design, and call this number 's'
count the number of threads in your design, and call this number 't'
now, raise t to the s-th power; this is roughly the number of hairs you are likely to lose while debugging the resulting code.
(I personally have run afoul of code that has over 50 singletons with 10 different threads all racing to get to .getInstance() first)
Related
Recently a fellow worker showed to me a code like this:
void SomeClass::function()
{
static bool init = false;
if (!init)
{
// hundreds of lines of ugly code
}
init = true;
}
He wants to check if SomeClass is initialized in order to execute some piece of code once per Someclass instance but the fact is that only one instance of SomeClass will exist in all the lifetime of the program.
His question were about the init static variable, about when it's initialized. I've answered that the initialization occurs once, so the value will be false at first call and true the rest of its lifetime. After answering I've added that such use of static variables is bad practice but I haven't been able to explain why.
The reasons that I've been thinking so far are the following:
The behaviour of static bool init into SomeClass::function could be achieved with a non-static member variable.
Other functions in SomeClass couldn't check the static bool init value because it's visibility is limited to the void SomeClass::function() scope.
The static variables aren't OOPish because they define a global state instead of a object state.
This reasons looks poor, unclever and not very concrete to me so I'm asking for more reasons to explain why the use of static variables in function and member-function space are a bad practice.
Thanks!
This is certainly a rare occurrence, at least, in good quality code, because of the narrow case for which it's appropriate. What this basically does is a just-in-time initialization of a global state (to deliver some global functionality). A typical example of this is having a random number generator function that seeds the generator at the first call to it. Another typical use of this is a function that returns the instance of a singleton, initialized on the first call. But other use-case examples are few and far between.
In general terms, global state is not desirable, and having objects that contain self-sufficient states is preferred (for modularity, etc.). But if you need global state (and sometimes you do), you have to implement it somehow. If you need any kind of non-trivial global state, then you should probably go with a singleton class, and one of the preferred ways to deliver that application-wide single instance is through a function that delivers a reference to a local static instance initialized on the first call. If the global state needed is a bit more trivial, then doing the scheme with the local static bool flag is certainly an acceptable way to do it. In other words, I see no fundamental problem with employing that method, but I would naturally question its motivations (requiring a global state) if presented with such code.
As is always the case for global data, multi-threading will cause some problems with a simplistic implementation like this one. Naive introductions of global state are never going to be inherently thread-safe, and this case is no exception, you'd have to take measures to address that specific problem. And that is part of the reasons why global states are not desirable.
The behaviour of static bool init into SomeClass::function could be achieved with a non-static member variable.
If there is an alternative to achieve the same behavior, then the two alternatives have to be judged on the technical issues (like thread-safety). But in this case, the required behavior is the questionable thing, more so than the implementation details, and the existence of alternative implementations doesn't change that.
Second, I don't see how you can replace a just-in-time initialization of a global state by anything that is based on a non-static data member (a static data member, maybe). And even if you can, it would be wasteful (require per-object storage for a one-time-per-program-execution thing), and on that ground alone, wouldn't make it a better alternative.
Other functions in SomeClass couldn't check the static bool init value because it's visibility is limited to the void SomeClass::function() scope.
I would generally put that in the "Pro" column (as in Pro/Con). This is a good thing. This is information hiding or encapsulation. If you can hide away things that shouldn't be a concern to others, then great! But if there are other functions that would need to know that the global state has already been initialized or not, then you probably need something more along the lines of a singleton class.
The static variables aren't OOPish because they define a global state instead of a object state.
OOPish or not, who cares? But yes, the global state is the concern here. Not so much the use of a local static variable to implement its initialization. Global states, especially mutable global states, are bad in general and should never be abused. They hinder modularity (modules are less self-sufficient if they rely on global states), they introduce multi-threading concerns since they are inherently shared data, they make any function that use them non-reentrant (non-pure), they make debugging difficult, etc... the list goes on. But most of these issues are not tied to how you implement it. On the other hand, using a local static variable is a good way to solve the static-initialization-order-fiasco, so, they are good for that reason, one less problem to worry about when introducing a (well-justified) global state into your code.
Think multi-threading. This type of code is problematic when function() can be called concurrently by multiple threads. Without locking, you're open to race conditions; with locking, concurrency can suffer for no real gain.
Global state is probably the worst problem here. Other functions don't have to be concerned with it, so it's not an issue. The fact that it can be achieved without static variable essentially means you made some form of a singleton. Which of course introduces all problems that singleton has, like being totally unsuitable for multithreaded environment, for one.
Adding to what others said, you can't have multiple objects of this class at the same time, or at least would they not behave as expected. The first instance would set the static variable and do the initialization. The ones created later though would not have their own version of init but share it with all other instances. Since the first instance set it to true, all following won't do any initialization, which is most probably not what you want.
I'm wondering about this. I've heard that global variables are bad, that they hurt the maintainability, usability, reusability, etc. of the code. But in this case, what can I do otherwise? Namely, I have a "pseudo-random number generator" (PRNG) and as one may know, they involve an internal state that changes every time new random numbers are generated. But this seems like the kind of thing that needs to be a global! Or a "static" member of an RNG class, but that's essentially a global! And globals are bad!
So, what can I do? The obvious thing is to have something like this (really stripped down):
class RNG {
private:
StateType state; // this is the thing one may be tempted
// to make "static", which ruins the
// whole idea
public:
RNG(); // constructor seeds the RNG
~RNG();
int generateRandomInt();
};
But we need to seed that good, if we're going to create an instance of this every time we need a random number in some function or class. Using the clock may not work, since what if two instances of type "RNG" are created too close together? Then they get the same seed and produce the same random sequence. Bad.
We could also create one master RNG object and pass it around with pointers (instead of making it global, which would put us back on square 1), so that classes that need random numbers get a pointer to the RNG object in them. But then I run into a problem involving save/load of these objects to/from disk -- we can't just "save the RNG" for each instance, since we have only one RNG object. We'd have to instead pass an RNG into the load routines, which might give those routines different argument lists than for other objects that don't use the RNG. This would be a problem if, e.g. we wanted to use a common "Saveable" base class for everything that we can load/save. So, what to do? Eliminate the common "Saveable" base and just adopt a convention for how the load/save routines are to be made (but isn't that bad in and of itself? Oy!)?
What is the best solution to this that avoids the hostile-to-maintainability problems of globals yet also does not run into these new problems?
Or is it in fact okay to use a global here, as after all, that's how the "rand()" builtin works anyway? But then I hear that little thing in the back of my mind saying "but... but but but, globals are bad! Bad!" And from what I've read, there seem to be fairly good reasons to think them bad. But it seems like avoiding them creates new kinds of difficulties, like this one. It certainly seems harder to avoid globals than avoid "goto"s, for example.
There's some merit to your reluctance. You may want to substitute another generator for testing for example, that spits out a deterministic sequence that contains some edge cases.
Dependency Injection is one popular method for avoiding globals.
A random number generator is one of those things that is more OK to be global. You can think of it as:
-A RandomNumberFactory, a design pattern that uses a global factory, and it builds random numbers for you. The factory is of course constant semantically (in C++ you might use the keyword "mutable" internally, if that means anything to you.)
-A global constant (global constants are ok, right?) that gives you read-only access to the global constant randomNumber. randomNumber just happens to be non-deterministic, but it's constant in that of course no application is going to write to it.
-And besides, what's the worst that could happen? In a multithreaded application your RNG will yield non-deterministic behavior? Gasp. As #Mark Ransom pointed out above, yes that is actually a drawback as it makes testing harder. If this is a concern to you, you might consider a design pattern that writes this out.
It sometimes makes sense to use globals. No one can categorically say your code should not have any global variables, period.
What you do need is to be aware of the issues that can arise from global variables. If your application's logic needs global variables and it is possible for it to be called from a multi-threaded environment, then there is nothing inherently wrong with that, but you must take care to use locking, mutexes, and/or atomic reads/writes to ensure correct behavior.
I have a class that represents a data stream, it basically
reads or writes into a file, but first the data are being encrypted/decrypted and there is also an underlying codec object that handles the media being accessed.
I'm trying to write this class in a RAII way and I'd like a clean, nice, usable design.
What bothers me is that right now there is a lot of work being done in the constructor.
Before the object's I/O routines can be safely used, first of all the codec needs to initialized (this isn't very demanding), but then a key is taken into account and crypto and other things are intialized - these require some analysis of the media which takes quite a lot of computation.
Right now I'm doing all this in the constructor, which makes it take a long time. I'm thinking of moving the crypto init stuff (most work) out of the ctor into a separate method (say, Stream::auth(key)), but then again, this would move some responsibility to the user of the class, as they'd be required to run auth() before they call any I/O ops. This also means I'd have to place a check in the I/O calls to verify that auth() had been called.
What do you think is a good design?
P.S. I did read similar question but I wasn't really able to apply the answers on this case. They're mostly like "It depens"... :-/
Thanks
The only truly golden unbreakable rule is that the class must be in a valid, consistent, state after the constructor has executed.
You can choose to design the class so that it is in some kind of "empty"/"inactive" state after the constructor has run, or you can put it directly into the "active" state that it is intended to be in.
Generally, it should be preferred to have the constructor construct your class. Usually, you wouldn't consider a class fully "constructed", until it's actually ready to be used, but exceptions do exist.
However, keep in mind that in RAII, one of the key ideas is that the class shouldn't exist unless it is ready, initalized and usable. That's why its destructor does the cleanup, and that's why its constructor should do the setup.
Again, exceptions do exist (for example, some RAII objects allow you to release the resource and perform cleanup early, and then have the destructor do nothing.)
So at the end of the day, it depends, and you'll have to use your own judgment.
Think of it in terms of invariants. What can I rely on if I'm given an instance of your class? The more I can safely assume about it, the easier it is to use. If it might be ready to use, and might be in some "constructed, but not initialized" state, and might be in a "cleaned up but not destroyed" state, then using it quickly becomes painful.
On the other hand, if it guarantees that "if the object exists, it can be used as-is", then I'll know that I can use it without worrying about what was done to it before.
It sounds like your problem is that you're doing too much in the constructor.
What if you split the work up into multiple smaller classes? Have the codec be initialized separately, then I can simply pass the already-initialized codec to your constructor. And all the authentication and cryptography stuff and whatnot could possibly be moved out into separate objects as well, and then simply passed to "this" constructor once they're ready.
Then the remaining constructor doesn't have to do everything from scratch, but can start from a handful of helper objects which are already initialized and ready to be used, so it just has to connect the dots.
you could just place the check in the IO calls to see if auth has been called, and if it has, then continue, if not, then call it.
this removes the burden from the user, and delays the expense until needed.
Basically, this all boils down to which design to choose from the following three:
Designs
Disclaimer: this post is not encouraging the use of exception specifications or exceptions for that matter. The errors may equivalently be reported using error codes if you wish. Exception specifications as used here are just meant to illustrate when different errors can occur using a concise syntax.
Design 1
This is the most recurring design out there, and totally non-RAII. The constructor just puts the object in some stale state and each instance must be initialized manually after construction takes place.
class SecureStream
{
public:
SecureStream();
void initialize(Stream&,const Key&) throw(InvalidKey,AlreadyInitialized);
std::size_t get( void*,std::size_t) throw(NotInitialized,IOError);
std::size_t put(const void*,std::size_t) throw(NotInitialized,IOError);
};
Pros:
Users have control over when to invoke the "heavy" initialization process
The object can be created before the key exists. This is important for frameworks such as COM, where all objects must have a default constructor (the CoCreateObject() does not allow you to forward extra arguments the object constructor). Sometimes, there are still workarounds, such as a builder object.
Cons:
Objects must be checked for the stale state before using the object. This may be enforced by the object by returning an error code or throwing an exception. Personally, I hate objects that allow me to use them and just appear to ignore my calls (e.g. a failed std::ostream).
Design 2
This is the RAII approch. Make sure the object is 100% usable with no extra artefacts (e.g. manually calling stream.initialize(...); on each instance.
class SecureStream
{
public:
SecureStream(Stream&,const Key&) throw(InvalidKey);
std::size_t get( void*,std::size_t) throw(IOError);
std::size_t put(const void*,std::size_t) throw(IOError);
};
Pros:
The object can always be assumed to be in a valid state. This is so much simpler to use.
Cons:
Constructor might take a long time to execute.
All required arguments must be available at the instance construction. This has once in a while been a problem for me, especially if most other objects in the code base use design #1.
Design 3
Somewhat of a compromise between the two previous cases. Don't initialize yet, but have the other methods lazily invoke the internal .initialize(...) method when necessary.
class SecureStream
{
public:
SecureStream(Stream&,const Key&);
std::size_t get( void*,std::size_t) throw(InvalidKey,IOError);
std::size_t put(const void*,std::size_t) throw(InvalidKey,IOError);
private:
void initialize() throw(InvalidKey);
};
Pros:
Almost as easy to use as design #1. Almost (see below).
Cons:
If the initialization step may fail, it may now fail anywhere there is a first call to any of the public methods. Proper error handling for this scenario is extremely difficult.
Discussion
If you absolutely must pay for the initialization for every instance, then design #1 is out of the question as it just results in more bugs in the software.
The question is just about when to pay for the initialization cost. Do you prefer paying it upfront, or on first use? In most scenarios, I prefer paying upfront because I don't want to assume users can handle errors later in the program. However, there might be specific threading semantics in your program, and you might not be able to stall threads at creation time (or, conversely, at use time).
In any case, you can still get the benefits of design #3 by using dynamic allocation of the class in design #2.
Conclusion
Basically, if the only reason you are hesitating is for some philosophical ideal where constructors execute quickly, I would just go with the pure RAII design.
There's no hard and fast rule on this, but in general it's best to avoid heavy constructors for two reasons that come to mind (maybe others as well):
The order of the objects created intializer list can give rise to subtle bugs
What to do with exceptions in the constructor? Will you need to handle partially-constructed objects in your app?
What is a good way to share an instance of an object between several classes in a class hierarchy? I have the following situation:
class texture_manager;
class world {
...
std::vector<object> objects_;
skybox skybox_;
}
I currently implemented texture_manager as a singleton, and clients call its instancing method from anywhere in the code. texture_manager needs to be used by objects in the objects_ vector, by skybox_, and possibly by other classes as well that may or may not be part of the world class.
As I am trying to limit the use of singletons in my code, do you recommend any alternatives to this approach? One solution that came to mind would be to pass a texture_manager reference as an argument to the constructors of all classes that need access to it. Thanks.
The general answer to that question is to use ::std::shared_ptr. Or if you don't have that, ::std::tr1::shared_ptr, or if you don't have that, ::boost::shared_ptr.
In your particular case, I would recommend one of a few different approaches:
One possibility is, of course, the shared_ptr approach. You basically pass around your pointer to everybody who needs the object, and it's automatically destroyed when none of them need it anymore. Though if your texture manager is going to end up with pointers to the objects pointing at it, you're creating a reference cycle, and that will have to be handled very carefully.
Another possibility is just to declare it as a local variable in main and pass it as a pointer or reference to everybody who needs it. It won't be going away until your program is finished that way, and you shouldn't have to worry about managing the lifetime. A bare pointer or reference is just fine in this case.
A third possibility is one of the sort of vaguely acceptable uses of something sort of like a singleton. And this deserves a detailed explanation.
You make a singleton who's only job is to hand out useful pointers to things. A key feature it has is the ability to tell it what thing to hand out a pointer to. It's kind of like a global configurable factory.
This allows you to escape from the huge testing issues you create with a singleton in general. Just tell it to hand out a pointer to a stub object when it comes time to test things.
It also allows you to escape from the access control/security issue (yes, they create security issues as well) that a singleton represents for the same reason. You can temporarily tell it to pass out a pointer to an object that doesn't allow access to things that the section of code you're about to execute doesn't need access to. This idea is generally referred to as the principle of least authority.
The main reason to use this is that it saves you the problem of figuring out who needs your pointer and handing it to them. This is also the main reason not to use it, thinking that through is good for you. You also introduce the possibility that two things that expected to get the same pointer to a texture manager actually get pointers to a different texture manager because of a control flow you didn't anticipate, which is basically the result of the sloppy thinking that caused you to use the Singleton in the first place. Lastly, Singletons are so awful, that even this more benign use of them makes me itchy.
Personally, in your case, I would recommend approach #2, just creating it on the stack in main and passing in a pointer to wherever it's needed. It will make you think more carefully about the structure of your program, and this sort of object should probably live for your entire program's lifetime anyway.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How much work should be done in a constructor?
I'm strugging with some advice I have in the back of my mind but for which I can't remember the reasoning.
I seem to remember at some point reading some advice (can't remember the source) that C++ constructors should not do real work. Rather, they should initialize variables only. The advice went on to explain that real work should be done in some sort of init() method, to be called separately after the instance was created.
The situation is I have a class that represents a hardware device. It makes logical sense to me for the constructor to call the routines that query the device in order to build up the instance variables that describe the device. In other words, once new instantiates the object, the developer receives an object which is ready to be used, no separate call to object->init() required.
Is there a good reason why constructors shouldn't do real work? Obviously it could slow allocation time, but that wouldn't be any different if calling a separate method immediately after allocation.
Just trying to figure out what gotchas I not currently considering that might have lead to such advice.
I remember that Scott Meyers in More Effective C++ recommends against having a superfluous default constructor. In that article, he also touched on using methods liked Init() to 'create' the objects. Basically, you have introduced an extra step which places the responsibility on the client of the class. Also, if you want to create an array of said objects, each of them would have to manually call Init(). You can have an Init function which the constructor can call inside for keeping the code tidy, or for the object to call if you implement a Reset(), but from experiences it is better to delete an object and recreate it rather than try to reset its values to default, unless the objects is created and destroyed many times real-time (say, particle effects).
Also, note that constructors can perform initialization lists which normal functions could not.
One reasons why one may caution against using constructors to do heavy allocation of resources is because it can be hard to catch exceptions in constructors. However, there are ways around it. Otherwise, I think constructors are meant to do what they are supposed to do - prepare an object for its initial state of execution (important for object creation is resource allocation).
The one reason not to do "work" in the constructor is that if an exception is thrown from there, the class destructor won't get called. But if you use RAII principles and don't rely on your destructor to do clean up work, then I feel it's better not to introduce a method which isn't required.
Depends on what you mean by real work. The constructor should put the object into a usable state, even if that state is a flag meaning it hasn't yet been initialised :-)
The only rationale I've ever come across for not doing real work would be the fact that the only way a constructor can fail is with an exception (and the destructor won't be called in that case). There is no opportunity to return a nice error code.
The question you have to ask yourself is:
Is the object usable without calling the init method?
If the answer to that is "No", I would be doing all that work in the constructor. Otherwise you'll have to catch the situation when a user has instantiated but not yet initialised and return some sort of error.
Of course, if you can re-initialise the device, you should provide some sort of init method but, in that case, I would still call that method from the constructor if the condition above is met.
In addition to the other suggestions regarding exception handling, one thing to consider when connecting to a hardware device is how your class will handle the situation where a device is not present or communication fails.
In the situation where you can't communicate with the device, you may need to provide some methods on your class to perform later initialization anyway. In that case, it may make more sense to just instantiate the object and then run through an initialization call. If the initialization fails, you can just keep the object around and try to initialize communication again at a later time. Or you may need to handle the situation where communication is lost after initialization. In either case, you will probably want to think about how you will design the class to handle communication problems in general and that may help you decide what you want to do in the constructor versus an initialization method.
When I've implemented classes that communicate with external hardware, I've found it easier to instantiate a "disconnected" object and provide methods for connecting and setting up initial status. This has generally provide more flexibility connecting/disconnecting/reconnecting with the device.
The only real reason is Testability. If your constructors are full of "real work", that usually means the objects can only be instantiated within a fully initialized, running application. It's a sign the object/class needs further decomposition.
When using a constructor and an Init() method you have a source of error. In my experience you will encounter situation where someone forgets to call it, and you might have a subtle bug in your hands. I would say you shouldn't do much work in your constructor but if any init method is needed, then you have a non-trivial construction scenario, and it is about time to look at the creational patterns. A builder function or a factory be wise to have a look at. With a private constructor making sure that no one except your factory or builder function actually build the objects, so you can be sure that it is always constructed correctly.
If your design allow for mistakes in implementation, someone will do those mistakes. My friend Murphy told me that ;)
In my field we work with loads of similar hardware related situations. Factories gives us both testability, security and better ways of failing construction.
It is worth considering lifetime issues and connecting/reconnecting, as Neal S. points out.
If you fail to connect to a device at the other end of a link then it is often the case that the 'device' at your end is usable and will be later if the other end gets its act together. Examples being network connections etc.
On the other hand if you try and access some local hardware device that does not exist and will never exist within the scope of your program (for example a graphics card that is not present) then I think this is a case where you want to know this in the constructor, so that the constructor can throw and the object can not exist. If you don't then you may end up with an object that is invalid and will always be so. Throwing in the constructor means that the object will not exist, and thus functions can't be called on that object. Obviously you need to be aware of cleanup issues if you throw in a constructor, but if you don't in cases like this then you typically end up with validation checks in all functions that may be called.
So I think that you should do enough in the constructor to ensure you have a valid, usable, object created.
I'd like to add my own experience there.
I won't say much about the traditional debate Constructor/Init... for example Google guidelines advise against anything the in the Constructor but that's because they advise against Exceptions and the 2 work together.
I can speak about a Connection class I use though.
When the Connection class is created, it will attempt to actually connect itself (at least, if not default constructed). If the Connection fails... the object is still constructed and you don't know about it.
When you try to use the Connection class you are thus in one of 3 cases:
no parameter has ever been precised > exception or error code
the object is actually connected > fine
the object is not connected, it will attempt to connect > this succeeds, fine, this fails, you get an exception or an error code
I think it's quite useful to have both. However, it means that in every single method actually using the connection, you need to test whether or not it works.
It's worth it though because of disconnection events. When you are connected, you may lose the connection without the object knowing about it. By encapsulating the connection self-check into a reconnect method that is called internally by all methods needing a working connection, you really isolate the developers from dealing with the issues... or at least as much as you can since when everything fails you have no other solution that letting them know :)
Doing "real work" in a constructor is best avoided.
If I setup database connections, open files etc inside a constructor and if in doing so one of them raise an exception then it would lead to a memory leak. This will compromise your application's exception safety.
Another reason to avoid doing work in a constructor is that it would make your application less testable. Suppose you are writing a credit-card payment processor. If say in CreditCardProcessor class's constructor you do all the work of connecting to a payment gateway, authentate and bill the credit card how do I ever write unit tests for CreditCardProcessor class?
Coming to your scenario, if the routines that query the device do not raise any exceptions and you are not going to test the class in isolation then there is its probably preferable to do work in the constructor and avoid calls to that extra init method.
There are a couple reasons I would use separate constructor/init():
Lazy/Delayed initialization. This allows you to create the object quickly, fast user response, and delay a more lengthy initialization for later or background processing. This is also a part of one or more design patterns concerning reusable object pools to avoid expensive allocation.
Not sure if this has a proper name, but perhaps when the object is created, the initialization information is unavailable or not understood by whoever is creating the object (for example, bulk generic object creation). Another section of code has the know-how to initialize it, but not create it.
As a personal reason, the destructor should be able to undo everything the constructor did. If that involves using internal init/deinit(), no problem, so long as they are mirror images of each other.