Я реализую приложение в Gtkmm и составляю во время выполнения Интерфейс Пользователя, реализованный в Glade.
Тема состоит в том, что я это составляю в строителе класса, как он во время выполнения, может появляться какой-то недостаток в компиляции и давать мне исключение, эта компиляция решающая, если он не следует, не собирает себе интерфейс и класс не instanciada правильно.
Из-за хороших практик, я не хочу быть должным возвращать исключение в строителе, желание который строитель или возвратил данная память или один nullptr
.
Мой строитель - следующий:
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
Что желание состоит в том, чтобы, если не добиваются компиляции во время выполнения по какому-то разуму, останавливать распределение памяти для этого объекта и возвратился один nullptr
.
Каков лучший способ, чтобы это делать?.
В зернышко: ты не можешь .
Во-первых, строители не могут возвращать совсем не . Ваш misi¦n в инициализировании блока памяти в известное состояние, но вышеупомянутый блок должен быть доступен перед ejecuci¦n c¦digo строителя .
Даже призыв к new
разлагается в 2 шагах: размещает из памяти и invocaci¦n строителя . Но всегда, всегда , память должна быть доступна во-первых. Следовательно, даже не используя new
podrÃ: s получать то, к чему ты стремишься:
FeAFeSinTiempo *ptr = nullptr;
try {
ptr = new FeAFeSinTiempo( );
} catch( ... ) {
// Ignoramos las excepciones.
}
std::cout << reinterpret_cast< void * >( ptr ) << '\n';
0x556bbb71e005
всегда mostrarÃ: direcci¦n, отличный от nullptr
, независимо, которого строитель бросил, или ты не заявил процессуальный отвод (кроме, если у нас есть excepci¦n bad_alloc
, но эта бросается в ошибках резерва памяти, перед тем, как называть строителя).
, Если podr¦-схвати, с другой стороны, изменять указатель в блоке catch( )
:
FeAFeSinTiempo *ptr = nullptr;
try {
ptr = new FeAFeSinTiempo( );
} catch( const std::bad_alloc & ) {
// Aquí no hacemos nada.
} catch( ... ) {
delete ptr;
ptr = nullptr;
}
std::cout << reinterpret_cast< void * >( ptr ) << '\n';
0x000000000000
Из всех форм, твоего планирования не правилен. Если случается excepci¦n, c¦digo в continuaci¦n не работает, а следовательно не необходимо, чтобы ты реализовал больше проверок в этом уровне, хотя если в верхнем уровне:
class FeAFeSinTiempo {
public:
FeAFeSinTiempo::FeAFeSinTiempo( ) {
try {
//Compilación en tiempo de ejecución
_refGridContenedorPrincipal = Gtk::Builder::create_from_string( _interfazGlade );
}
//Aquí instancio los otros objetos de clase
}
...
};
int main( ) {
try {
FeAFeSinTiempo feafe;
feafe.doIt( );
} catch( const std::bad_alloc & ) {
std::cerr << "Sin memoria :-(\n";
} catch( const Gtk::BuilderError &ex ) {
std::cerr << "Metedura de pata mia :-(\n" << ex.what( ) << '\n';
} catch( ... ) {
std::cerr << "Error totalmente inesperado :-O\n";
}
return 0;
}
то, что, если ты должен убеждаться, состоит в том, чтобы оставлять твою инстанцию в консистентном состоянии, хотя случатся исключения в строителе; и потом реализовывать соответствующие операции в разрушителе.