I am working on refactoring some of the old C-style code to bring it more into line with C++ code. I still am a bit new to C++
An example of the code I am working on is as follows
Errmsg foo{
ErrMsg err = NoError;
/*
Some Processing
*/
err = foo_cleanup(err,/* some parameters*/);
/*
Some More Processing
*/
return err;
}
I was thinking of developing a class so that
class foo_class
{
public:
foo_class(Errmsg errmsg_init&,/*Some other arguments */ ):
errmsg(&errmsg_init),
/*Initialize other parameters */{}
void foo_cleanup (/*Other parameters*/);
// same functionality, but since the source variable is available,
// it can be modified without having to return any variable
~foo_class(){foo_cleanup(/*Parameters*/);}
/*
Member functions
*/
private:
Errmsg* errmsg;
/*Some other parameters */
};
Errmsg foo{
ErrMsg err = NoError;
foo_class foo_obj(err);
/*
Some Processing
*/
// The class would be
//cleaned up before returning
// and the err variable would be
//modified in the destructor
return err;
}
Although I have been able to use something similar to this approach, I do not know if this will be portable.
Is this the right thing to do?
If not, do I just use pointers to initialize the class instead of passing the error message variable by reference? Or is there something else I can do?
I cannot use exceptions at the current stage because there are many function calls to/from external code which use a “return error message” approach still.
Leaving aside that you should if possible fix the calling code so that an exception is OK, you could use the two-phase construction idiom:
Now, exception-using code can call the multi-arg constructor (and get the object in a ready-to-use state), whereas exception-averse code can call the default constructor followed by
nothrow_init(and live with the fact that ifnothrow_initfails they have an unusable object on their hands, and it’s their responsibility to ensure that they don’t use it).In future, as you bring other parts of your code base into an exception-using state, you will find that the code in
initcalls things that can themselves throw. At that point you can start moving code around, so that thenothrow_initcalls aninitfunction that can throw, but catches any exceptions and turns them into error codes. Assuming it’s an internal class then eventually nothing will be usingnothrow_initand you can remove it.