Вместо того, чтобы рассказывать вам, как заставить конструктор возвращать значение null или как его подделать, позвольте мне предложить альтернативу: предложить способ избежать генерирования исключения, например, с помощью отложенной инициализации или не генерирующего конструктора. Однако, как только вы это сделаете, вам понадобится проверить правильность и убедиться, что любая попытка использовать недопустимый экземпляр вызывает исключение. Другими словами, вы откладываете исключение, а не избегаете его полностью.
Вот как:
У вас уже есть конструктор, который берет путь к файлу и загружает его, выбрасывая при неудаче. Переместите кишки в метод Load, который берет путь к файлу и возвращает bool, указывающий на успех. Затем измените конструктор так, чтобы он просто вызывал Load и выбрасывал false. В Load убедитесь, что сразу возвращено значение false, если экземпляр правильно инициализирован. Затем добавьте деструктор по умолчанию и метод IsValid.
за Дениса:
Теперь добавьте второй конструктор, который принимает логическое значение для управления созданием исключения, и рассмотрите возможность перевода Load в private, и в этом случае вы также удалите конструктор по умолчанию.
Это дает вам все, о чем вы можете просить, без создания неуправляемого кода. Это должно выглядеть примерно так:
// Per Dennis, should go away if Load becomes private.
Image()
{
_valid = false;
}
Image(const string& filepath)
{
if (!Load(filepath))
throw new exception("Cannot open image.");
}
// Per Dennis.
Image(const string& filepath, bool doThrow)
{
if (!Load(filepath) && doThrow)
throw new exception("Cannot open image.");
}
// Per Dennis, this should probably be made private now.
bool Load(const string& filepath)
{
if (_valid)
return false;
// Try to load...
_valid = WhetherItLoadedExpression;
return _valid;
}
bool IsValid()
{
return _valid;
}
void Draw()
{
if (!IsValid())
throw new exception("Invalid object.");
// Draw...
}
редактировать
См. Ниже изменения, сделанные в ответ на комментарий Денниса.