views:

369

answers:

5

I would like to have the constructor abort object construction whenever it encounters certain error code (e.g. if the following is encountered):

CudaObj::CudaObj(InsertionSim *theSim)
{
    // Setup
    if(cublasInit() == CUBLAS_STATUS_NOT_INITIALIZED) {
     printf("CUBLAS init error.\n");
     return -1;  // abort here rather than return a value
    }

        ...
}

What would be the easiest way for this to be accomplished? Would it be exception handling?

+12  A: 

I think the idiomatic way is to throw an exception from the constructor to emphasize that the object is not in a valid state.

AraK
That, or split the fallible code into a member init() function. Personally, I'd go with the exception way, but it's good to know your options.
Twisol
@Twisol. public init() methods are not a good idea. Applying RAII, the object exists as soon as the constructor finishes without throwing. If you use the init method, after the constructor and before the init() you have a valid object (in language terms) and an invalid object (in business logic terms). And users will generally fail to call init(). I'm glad you prefer the exception version over init though
Glen
+1  A: 

Exception handling would definitely be my choice, especially in the case shown above, which really is an exception to the proper flow of the program. Alternatively, you could let the constructor return, and have a function 'IsInitilized()' or some such which would allow you/the user to verify it was completed appropriately. This however does impose an additional burden on the user of your class, that being said you might as well go with exception handling as it is a well-accepted way of imposing this burden (they have to catch the exception).

DeusAduro
I am not a fan of this method, although I am guilty of using it. I'm of the opinion that an object should always be in a valid state, and errors should be clear the moment they appear.
Smashery
A: 

If you'd rather not use exceptions (although admittedly, I do in this situation), you could make a static method of the class in which you ask "Can I construct an object with these parameters?" and require that that method be called before you construct. So effectively, your constructor would become

CudaObj::CudaObj(InsertionSim *theSim)
{
    // Setup
    ASSERT(cublasInit() == CUBLAS_STATUS_NOT_INITIALIZED)    
        ...
}

And then you'd need

BOOL CudaObj::CanConstruct(InsertionSim *theSim)
{
    // Check if we can construct
    return TRUE; // Or FALSE
}

So your code would be

if (CudaObj::CanConstruct(pSim))
{
    pObj = new CudaObj(pSim);
}
else
{
    // Handle invalid parameter
    ...
}

You could also provide a convenience method to do both (using OUT arguments, for instance).

Smashery
Not sure why this was downvoted, i mean its not what I would do... doesn't mean it wouldn't work though.
DeusAduro
@DeusAduro - I didn't down-vote it ... but one big problem is that it assumes that it is feasible to implement `CanConstruct` without doing the actual construction. This is not true in general.
Stephen C
@Stephen - Fair call. But then, I seem to recall having huge problems with exceptions across DLL boundaries, which could potentially make that solution infeasible itself.
Smashery
A: 

Use an exception, unless you have some reason that you aren't using exceptions in your program. The reason is that by using an exception, you prevent the constructor of the object from EVER thinking the object is valid.

Your other choices are to have an 'IsInitialized' method (which will return false if the constructor failed), or a trivial (empty) constructor, and a separate 'Initialize' method, which can return an error code. These strategies are good ones if you are avoiding exceptions, and may be useful in situations where you are incorporating C++ code into older C code.

Michael Kohne
A: 

While I prefer exceptions unless I have a VERY good reason not to, exceptions may have some drawbacks. This article lists some of the drawbacks and several alternatives to exception handling.
Even if you use only exceptions for your error handling, I still recommend reading it.

One other thing: IMO you should not limit your considerations to constructor errors. maintaining two different error handling infrastructures in one system is hard and error prone. Try to select an error handling method for the whole system.
although constructor error handling is a big factor in this decision making, it is not the only one.

Oren S