Как возвращать Null в строителе класса?

Я реализую приложение в 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.

Каков лучший способ, чтобы это делать?.

2
задан 09.08.2019, 21:06
1 ответ

В зернышко: ты не можешь .

Во-первых, строители не могут возвращать совсем не . Ваш 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;
}

то, что, если ты должен убеждаться, состоит в том, чтобы оставлять твою инстанцию в консистентном состоянии, хотя случатся исключения в строителе; и потом реализовывать соответствующие операции в разрушителе.

3
ответ дан 01.12.2019, 22:19