Какова лучшая техника для выхода от конструктора на состоянии ошибки в C++

Почему вы инициализируете вау в обратном вызове onLeave? Вам, вероятно, придется сделать это только один раз при загрузке страницы.

Попробуйте инициализировать его только один раз в обратном вызове afterRender:

$(document).ready(function() {
  $('#fullpage').fullpage({
    navigation: true,
    navigationPosition: 'right',
    scrollBar: true,
    afterRender: function() {
      new WOW().init();
    }
  });
  //methods
  $.fn.fullpage.setAllowScrolling(true);
});
20
задан Jack BeNimble 10 April 2009 в 16:32
поделиться

8 ответов

Лучшее предположение, вероятно, то, что говорит парашифт. Но, пожалуйста, прочитайте мое предупреждение также ниже.

См. Часто задаваемые вопросы по parashift 17.2

[17.2] Как я могу обработать конструктор что не получается?

Бросить исключение.

Конструкторы не имеют возвращаемого типа, поэтому невозможно использовать возврат коды. Лучший способ подать сигнал отказ конструктора, следовательно, бросить исключение. Если у вас нет возможность использования исключений, «наименее плохой» обходной путь, чтобы поставить объект в состояние "зомби" установить бит внутреннего состояния, чтобы объект действует вроде как он мертв хотя технически это все еще жив.

Идея "зомби" объекта имеет много минусов. Вам нужно добавить функция-член запроса ("инспектора") для проверьте этот бит "зомби", чтобы пользователи ваш класс может узнать, если их объект действительно жив, или если это зомби (т. е. «живой мертвец»), и почти в каждом месте, где вы построить один из ваших объектов (в том числе внутри более крупного объекта или массив объектов) нужно проверить этот флаг состояния через оператор if. Вы также хотите добавить if к вашему другие функции-члены: если объект это зомби, делать не-операции или, возможно, что-то более противное.

На практике «зомби» довольно уродливые. Конечно, вы должны предпочитаю исключения объектам зомби, но если у вас нет возможности используя исключения, объекты зомби могут будьте «наименее плохой» альтернативой.


Предостережение с бросанием исключений в конструкторе:

Будьте очень осторожны, хотя, потому что, если исключение выдается в конструкторе, деструктор класса не вызывается. Таким образом, вы должны быть осторожны при уничтожении объектов, которые вы уже создали, прежде чем будет сгенерировано исключение. Те же самые предупреждения применимы и к обработке исключений в целом, но, возможно, это немного менее очевидно при работе с конструктором.

class B
{
public:
    B()
    {

    }

    virtual ~B()
    {
        //called after D's constructor's exception is called
    }
};

class D : public B
{
public:
    D()
    {
        p = new char[1024];
        throw std::exception("test");
    }

    ~D()
    {
      delete[] p;
      //never called, so p causes a memory leak
    }

    char *p;
};

int main(int argc, char **argv)
{

    B *p;
    try
    {
        p = new D();
    }
    catch(...)
    {

    }


    return 0;
}

Защищенные / частные конструкторы с методом CreateInstance:

Другой способ обойти это - сделать ваш конструктор частным или защищенным и создайте метод CreateInstance, который может возвращать ошибки.

27
ответ дан 29 November 2019 в 23:48
поделиться

В общем, вы должны выбросить исключение. Альтернатива состоит в том, чтобы иметь какой-то наполовину правильно построенный объект, который пользователь должен каким-то образом протестировать, что он неизбежно потерпит неудачей.

4
ответ дан 29 November 2019 в 23:48
поделиться

Существует только 1 хороший способ выйти из конструктора, который содержит ошибку, то есть вызвать исключение.

Это действительно ошибка? Вы пытаетесь добавить слишком много в конструктор?

Часто люди пытаются вставить какое-то начальное взаимодействие в конструктор, например, добавив имя файла в конструктор файла. Ожидаете ли вы, что он сразу же откроет этот файл, или вы просто устанавливаете какое-то состояние, отличается ли оно от file.open (имя файла), нормально ли это в случае сбоя?

0
ответ дан 29 November 2019 в 23:48
поделиться

Бросить исключение. Посмотрите здесь для получения дополнительной информации: Ошибка обработки в конструкторе

0
ответ дан 29 November 2019 в 23:48
поделиться

Если объект, который вы ' повторное конструирование недопустимо из-за ошибки и должно быть утилизировано вызывающей стороной, тогда вам в значительной степени придется сгенерировать исключение. Это позволяет компилятору выполнять правильное освобождение ресурсов.

(Написание безопасных для исключений конструкторов требует некоторой осторожности - вкратце, вы должны использовать списки инициализаторов везде, где можете, а не использовать тело конструктора - но очень важно, если у вас есть такой случай, когда исключение является значительной возможностью.)

2
ответ дан 29 November 2019 в 23:48
поделиться

Вы можете выдать исключение, как уже упоминали другие, или вы также можете выполнить рефакторинг вашего кода, чтобы ваш конструктор не мог потерпеть неудачу. Если, например, вы работаете над проектом, в котором исключения отключены или запрещены, то последний - ваш лучший вариант.

Чтобы создать конструктор, который не может выйти из строя, рефакторинг кода, который потенциально может привести к сбою, в метод init () , и пусть конструктор выполняет как можно меньше работы, а затем потребуйте, чтобы все пользователи класса вызвали init () сразу после создания. Если init () завершится неудачно, вы можете вернуть код ошибки. Обязательно документируйте это в документации вашего класса!

Конечно, это несколько опасно, так как программисты могут забыть вызвать init () . Компилятор не может принудительно применить это, поэтому действуйте осторожно и постарайтесь, чтобы ваш код работал быстро, если init () не вызывается.

7
ответ дан 29 November 2019 в 23:48
поделиться

Лучше всего сделать исключение. Это то, для чего они здесь, и любая попытка дублировать поведение, которое вы получаете, может где-то потерпеть неудачу.

Если вы по какой-то причине не можете использовать исключение, используйте nothrow . Пример из Стандарта 18.4.1.1, раздел 9, выглядит следующим образом:

t* p2 = new(nothrow) T;    // returns 0 if it fails

Это технически форма нового размещения, но она должна либо возвращать полностью сформированный объект, либо нулевой указатель, который необходимо проверить, за исключением того, что никто не будет

Если у вашего класса может быть объект, который существует, но не инициализирован должным образом, вы можете иметь элемент данных, который служит в качестве флага относительно того, полезен класс или нет. Опять же, никто не будет проверять этот флаг в живом коде.

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

Действительно, исключения - лучший способ.

0
ответ дан 29 November 2019 в 23:48
поделиться

Если после возражения вы не можете выполнить свои действия - вы должны бросить. Если это возможно - зарегистрируйте вашу ошибку и измените логику построения.

1
ответ дан 29 November 2019 в 23:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: