Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Первое: если кидать в конструкторе исключение, то для уже созданных объектов не будут вызваны деструкторы и могут возникнуть утечки. Так что будте осторожны.
Второе: как вариант сделать статическю функцию а Вашего класса, которая будет создавать объект соединения и возвращать указатель на него. Если соединение не создастся, то она легко может вернуть NULL.
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
можно возложить обязанность по созданию экземпляра этого класса на отдельный класс, возвращающий указатель на внось созданный объект и NULL в случае неудачи — см. паттерн builder
Rothmans wrote:
>> > R>...к сожалению для нелюбителей исключений сам язык сейчас кидает >> > исключения достаточно часто. Поэтому от того, кидает пользователь >> > исключения или нет, уже мало что зависит... > >> > А поясните, пожалуйста, где будут утечки в последнем приведенном примере? > _>Если второй new выбросит исключение, то деструктор не вызовется и не > удалит память, выделенную в первом new > > Насколько велика вероятность, что new int[100] кинет исключение (именно
Нельзя быть чуточку беременным.
Утечка либо возможна, либо нет. Ничто не мешает писать код без возможных утечек (кроме неопытности).
> вот такой небольшой запрашиваемый кусочек памяти)?
А насколько велика вероятность, что ты будешь запрашивать именно 100? А не заданный переданным параметром размер?
> Был бы благодарен, если бы увидел пример, как правильно делать в этом > случае (без использования буста, пожалйуста).
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта.
Да.
AS>Есть ли какой-то другой вариант решения этого?
Отложенная инициализация:
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Здравствуйте, Stuw, Вы писали:
S>Здравствуйте, AlexeyStaf, Вы писали:
AS>>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
S>Первое: если кидать в конструкторе исключение, то для уже созданных объектов не будут вызваны деструкторы и могут возникнуть утечки. Так что будте осторожны.
15.2/2
An object that is partially constructed or partially destroyed will have destructors executed for all of its fully constructed subobjects, that is, for subobjects for which the constructor has completed execution and the destructor has not yet begun execution.
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, _Winnie, Вы писали:
_W>>Здравствуйте, AlexeyStaf, Вы писали:
AS>>>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
C>Лучше так:
Если то, что объект не может создаться — нормальное поведение программы, то исключения не стоит использовать ни с какой точки зрения.
Ни с точки зрения эффективности, ни с точки зрения удобства (в данном случае, правда, синтаксический оверхед примерно одинаковый, если не извращаться с operator?: ), ни с точки зрения "фелософии праэктирования".
C>
Здравствуйте, _DAle_, Вы писали:
S>>Первое: если кидать в конструкторе исключение, то для уже созданных объектов не будут вызваны деструкторы и могут возникнуть утечки. Так что будте осторожны.
_DA>
15.2/2
_DA>An object that is partially constructed or partially destroyed will have destructors executed for all of its fully constructed subobjects, that is, for subobjects for which the constructor has completed execution and the destructor has not yet begun execution.
Ну и что?
Если не пользоваться умными указателями или специально не озаботиться решением этой проблемы,
то утечки будут
Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, AlexeyStaf, Вы писали:
AS>>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. B>Да.
AS>>Есть ли какой-то другой вариант решения этого? B>Отложенная инициализация: B>
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
сделай статический метод класса (к примеру, New()) в котором будешь создавать обьект, ловить исключения и возвращать NULL в случае неудачи. Или не статический а просто функцию. Или целую фабрику.
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Не совсем при создании:
struct My
{
My() { initialized_ = init(); }
operator bool() const { return initialized_; }
private:
bool init();
bool initialized_;
};
My obj;
if ( ! obj ) ...
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Здравствуйте, _Winnie, Вы писали:
_W>Здравствуйте, AlexeyStaf, Вы писали:
AS>>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
"Вернуть" из конструктора ничего нельзя. А уж как это сделать по-другому — есть масса разных способов. Можно кидать исключение. Можно потом, как уже посоветовали, завернуть поимку исключения внутрь метода-фабрики, чтобы не заниматься ловлей в клиентском коде. Можно просто в процессе конструкции выставлять флаг "сконструированности": получилось/не получилось и обрабатывать его позже. Можно опять же сделать метод-фабрику, в котром все потенциально неудачные действия делаются и проверяются еще до вызова конструктора, а сам конструктор уже работает "гарантированно". И т.д.
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Идиома виртуального конструктора — типа метод Create///
Идиома пустого объекта... Возвращай не нулевой указатель, а пустой объект базы....
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, _Winnie, Вы писали: _W>Здравствуйте, Centaur, Вы писали:
C>>Лучше так: _W>
_W> ни с точки зрения "фелософии праэктирования".
Правда, только в том случае, если при написании класса MyClass мы знаем, как он будет создаваться в Create. Но судя по тому, что автор топика хочет "вернуть NULL из конструктора", в данном случае MyClass знает, что его ошибка создания — нормальная ситуация.
Правильно работающая программа — просто частный случай Undefined Behavior
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Здравствуйте, Stuw, Вы писали:
S>Здравствуйте, AlexeyStaf, Вы писали:
AS>>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
S>Первое: если кидать в конструкторе исключение, то для уже созданных объектов не будут вызваны деструкторы и могут возникнуть утечки. Так что будте осторожны.
S>Второе: как вариант сделать статическю функцию а Вашего класса, которая будет создавать объект соединения и возвращать указатель на него. Если соединение не создастся, то она легко может вернуть NULL.
если произошло исключение в конструкторе, то объект считается не сконструированным и соответственно не будет вызван деструктор этого объекта, т.к. уничтожать в принципе нечего.. а вот для созданных до исключения членов деструкторы вызваны будут
Здравствуйте, AlexeyStaf, Вы писали:
AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
Раз в задаче конкретно указан NULL, значит решение чисто кодовое
и я не буду рассматривать возможные проектные решения для описанной
ситуации.
NULL может относиться только к динамическим объектам.
Следовательно, нужно переопределить operator new
А>Выкидывать исключения в конструкторе можно, но о возможных последствиях думать все равно надо.
Если ты будешь писать в таком стиле, то утечки у тебя будут независимо от того кидаешь ты исключения в конструкторе или нет. Достаточно взглянуть на такой пример:
...к сожалению для нелюбителей исключений сам язык сейчас кидает исключения достаточно часто. Поэтому от того, кидает пользователь исключения или нет, уже мало что зависит...
Андрей Тарасевич wrote:
> AS>Есть какой-то класс. В конструкторе этого класса я пытаюсь > соединиться с БД. Если соединение с БД не установлено, то дальнейшая > работа класса невозможна. Поэтому: как мне при создании экземпляра > класса вернуть NULL? Я так понял, что придется кидать исключение, но > тогда его придется отлавлявать в основной программе при создании > объекта. Есть ли какой-то другой вариант решения этого? > > "Вернуть" из конструктора ничего нельзя.
Здравствуйте, ois, Вы писали:
AS>>Есть какой-то класс. В конструкторе этого класса я пытаюсь соединиться с БД. Если соединение с БД не установлено, то дальнейшая работа класса невозможна. Поэтому: как мне при создании экземпляра класса вернуть NULL? Я так понял, что придется кидать исключение, но тогда его придется отлавлявать в основной программе при создании объекта. Есть ли какой-то другой вариант решения этого?
ois>Раз в задаче конкретно указан NULL, значит решение чисто кодовое ois>и я не буду рассматривать возможные проектные решения для описанной ois>ситуации. ois>NULL может относиться только к динамическим объектам. ois>Следовательно, нужно переопределить operator new
Конструктор начинает выполняться строго после того, как отработал operator new. Чтобы вернуть NULL в случае, когда инициализация объекта невозможна, operator new должен обладать даром ясновидения.
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, ois, Вы писали:
C>Конструктор начинает выполняться строго после того, как отработал operator new. Чтобы вернуть NULL в случае, когда инициализация объекта невозможна, operator new должен обладать даром ясновидения.
Если конструктор не имеет параметров или эти параметры не
нужны для соединения с БД, то ясновидения не нужно.
Впрочен, согласен, что моя идея плоха. Я просто старался
следовать условию задачи
А>>Выкидывать исключения в конструкторе можно, но о возможных последствиях думать все равно надо.
R>Если ты будешь писать в таком стиле, то утечки у тебя будут независимо от того кидаешь ты исключения в конструкторе или нет. Достаточно взглянуть на такой пример:
R>
R>...к сожалению для нелюбителей исключений сам язык сейчас кидает исключения достаточно часто. Поэтому от того, кидает пользователь исключения или нет, уже мало что зависит...
А поясните, пожалуйста, где будут утечки в последнем приведенном примере?
> R>...к сожалению для нелюбителей исключений сам язык сейчас кидает > исключения достаточно часто. Поэтому от того, кидает пользователь > исключения или нет, уже мало что зависит...
> А поясните, пожалуйста, где будут утечки в последнем приведенном примере?
Если второй new выбросит исключение, то деструктор не вызовется и не удалит память, выделенную в первом new
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
>> R>...к сожалению для нелюбителей исключений сам язык сейчас кидает >> исключения достаточно часто. Поэтому от того, кидает пользователь >> исключения или нет, уже мало что зависит...
>> А поясните, пожалуйста, где будут утечки в последнем приведенном примере? _>Если второй new выбросит исключение, то деструктор не вызовется и не удалит память, выделенную в первом new
Насколько велика вероятность, что new int[100] кинет исключение (именно вот такой небольшой запрашиваемый кусочек памяти)?
Был бы благодарен, если бы увидел пример, как правильно делать в этом случае (без использования буста, пожалйуста).
Здравствуйте, kan_izh, Вы писали:
_>Rothmans wrote:
>>> > R>...к сожалению для нелюбителей исключений сам язык сейчас кидает >>> > исключения достаточно часто. Поэтому от того, кидает пользователь >>> > исключения или нет, уже мало что зависит... >> >>> > А поясните, пожалуйста, где будут утечки в последнем приведенном примере? >> _>Если второй new выбросит исключение, то деструктор не вызовется и не >> удалит память, выделенную в первом new >> >> Насколько велика вероятность, что new int[100] кинет исключение (именно _>Нельзя быть чуточку беременным. _>Утечка либо возможна, либо нет. Ничто не мешает писать код без возможных утечек (кроме неопытности).
с таким подходом ловить исключения придется параноически везде (int a = 2+2; и то может кинуть исключение, если вся память вообще закончилась или процессор перегрелся )
>> вот такой небольшой запрашиваемый кусочек памяти)? _>А насколько велика вероятность, что ты будешь запрашивать именно 100? А не заданный переданным параметром размер?
если нужен массив в 100 целых, то вероятность, что потребуется что-то еще на данный момент 0. Правда тогда new становится не нужен и память можно выделять статически
Но я по сути не спорю. >> Был бы благодарен, если бы увидел пример, как правильно делать в этом >> случае (без использования буста, пожалйуста).
_>struct MyCoolClass _>{ _> std::vector m_p1, m_p2; _> MyCoolClass::MyCoolClass() _> { _> m_p1.resize(100); _> m_p2.resize(100); _> } _>}
Rothmans wrote:
> с таким подходом ловить исключения придется параноически везде (int a = > 2+2; и то может кинуть исключение, если вся память вообще закончилась > или процессор перегрелся )
Не может. Спецификация языка не предусматривает cpu_overheat_exception.
А память под "a" выделяется на стеке при входе в функцию, так что если это был последний байт, ничего страшного, память
уже есть выделенная, осталось сложить два числа и поместить в эту память.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, kan_izh, Вы писали:
_>Rothmans wrote:
>> с таким подходом ловить исключения придется параноически везде (int a = >> 2+2; и то может кинуть исключение, если вся память вообще закончилась >> или процессор перегрелся ) _>Не может. Спецификация языка не предусматривает cpu_overheat_exception. _>А память под "a" выделяется на стеке при входе в функцию, так что если это был последний байт, ничего страшного, память _>уже есть выделенная, осталось сложить два числа и поместить в эту память.
так и думал, что ты так парируешь
это я не смог придумать адекватный пример и написал чисто метафорически.