I am making an application in Gtkmm and I am compiling a User Interface made in Glade at runtime.
The issue is that I am compiling it in the constructor of the class, as it is at runtime, some problem may arise in the compilation and give me an exception, this compilation is crucial, if it does not work, the interface is not mounted and the class is not correctly instantiated.
For good practice, I don't want to have to return an exception in a constructor, I want the constructor to either return the given memory or a nullptr
.
My constructor is the following:
FeAFeSinTiempo::FeAFeSinTiempo()
{
bool intancia = false;
try
{
//Compilación en tiempo de ejecución
_refGridContenedorPrincipal = Gtk::Builder::create_from_string(_interfazGlade);
intancia = true;
}
catch(const Gtk::BuilderError &ex)
{
std::cerr << ex.what() << '\n';
}
if(intancia)
{
//Aquí instancio los otros objetos de clase
}
else
{
this = nullptr; //<== esto no es correcto
}
}//Constructor por defecto
What I want is that if runtime compilation fails for some reason, to stop allocating memory for that object and return a nullptr
.
What is the best way to do it?
To the point: you can't .
First of all, constructors can't return anything . Its mission is to initialize a block of memory to a known state, but this block must be available before the execution of the constructor code .
Even a call to
new
breaks down into 2 steps: memory allocation and constructor invocation . But always, always , the memory has to be available first. Therefore, even using it you will notnew
be able to achieve what you want:An address other than will always
nullptr
be returned , regardless of whether or not the constructor throws exceptions (except if we have an exceptionbad_alloc
, but that one is thrown on memory allocate errors, before the constructor is called).If you could, on the other hand, modify a pointer in the block
catch( )
:However, your approach is not correct. If an exception occurs, the code below is not executed, so you don't need to check further at that level, but at a higher level:
What you do have to make sure of is to leave your instance in a consistent state even if constructor exceptions are thrown; and then perform the relevant operations on the destructor.