Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.98/47: Рейтинг темы: голосов - 47, средняя оценка - 4.98
Заблокирован

Оператор new, как отменить создание объекта в конструкторе?

27.10.2014, 18:35. Показов 9912. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
class A
{
   public:
   A()
   {
      //cancel code ?
   };
}
Создаю экземпляр класса A* a = new A;, как можно отменить при определённых условиях создание экземпляра класса из конструктора, чтоб память под объект не выделилась и оператор new вернул бы nullptr.
Понятно, что можно кинуть throw какой - нибуть, но хотелось, чтоб вернулся именно ноль.

И кстати, про throw, если из конструктора кинуть throw, то будет ли выделена память под объект?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.10.2014, 18:35
Ответы с готовыми решениями:

Как отменить инициализацию класса в конструкторе New?
Есть следующий код: Class MyClass Sub New( doc as NotesDocument) if doc is nothyng then // тут хочется выйти из кода, но так...

Как в конструкторе сохранять имя копируемого объекта
Добрый вечер! Столкнулся со сложностью в конструкторе vb2010 express: при копировании (ctrl+c / ctrl+v или движением мыши с удерживанием...

Инициализация объекта в конструкторе
Доброго времени суток. Пытаюсь инициализировать переменную в конструкторе для последующего её юзанья в методах класса. Исход: #include...

28
Студент
 Аватар для MickeyBlueEyes
121 / 132 / 39
Регистрация: 07.04.2011
Сообщений: 503
27.10.2014, 18:50
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
как можно отменить при определённых условиях создание экземпляра класса из конструктора, чтоб память под объект не выделилась и оператор new вернул бы nullptr
Использовать фабрику:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A
{
   public:
     static A* create() {
       if(чтото) {
         return nullptr;
       }
       return new A();
     }
 
   private:
     A()
     { };
}
C++
1
A::create();
Добавлено через 4 минуты
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
И кстати, про throw, если из конструктора кинуть throw, то будет ли выделена память под объект?
Нет, будет автоматический delete.
1
Заблокирован
27.10.2014, 19:38  [ТС]
Цитата Сообщение от MickeyBlueEyes Посмотреть сообщение
Использовать фабрику:
стоп стоп, а разве стандартными способами нельзя как - то изменить поведение? (MSVS)
Цитата Сообщение от MickeyBlueEyes Посмотреть сообщение
Нет, будет автоматический delete.
Уже хорошо, а какой бы экзепшен кинуть, чтоб new автоматом вернуль ноль? Может что - то вроде out of memory ?

Добавлено через 4 минуты
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
стоп стоп, а разве стандартными способами нельзя как - то изменить поведение? (MSVS)
Хотя фабрика тоже хороша
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
27.10.2014, 19:43
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
стоп стоп, а разве стандартными способами нельзя как - то изменить поведение? (MSVS)
Нельзя. А если вы найдете что-то именно из "MSVS", то это уже не будет "стандартным".

Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
а какой бы экзепшен кинуть, чтоб new автоматом вернуль ноль? Может что - то вроде out of memory ?
Нет такого эксепшна. К моменту начала работы конструктора память уже успешно выделена. Поэтому для out of memory уже поздно.
0
Студент
 Аватар для MickeyBlueEyes
121 / 132 / 39
Регистрация: 07.04.2011
Сообщений: 503
27.10.2014, 19:45
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
а какой бы экзепшен кинуть, чтоб new автоматом вернуль ноль?
Ну new выбрасывает std::bad_alloc если выделить не удалось, но указатель будет содержать в себе то что было ему присвоено до этого, тоесть new в случае провала указатель ваш не тронет, а просто выбросит исключения, если явно не указать вот так:
C++
1
int* ptr = new (std::nothrow) int;
Тогда там будет ноль.
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
а разве стандартными способами нельзя как - то изменить поведение?
Так никак, я способов больше незнаю.
1
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
27.10.2014, 19:47
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
как можно отменить при определённых условиях создание экземпляра класса из конструктора, чтоб память под объект не выделилась и оператор new вернул бы nullptr.
можно переопределить new в своем классе который будет или не будет вызывать стандартный new
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
27.10.2014, 19:50
Цитата Сообщение от ValeryS Посмотреть сообщение
можно переопределить new в своем классе который будет или не будет вызывать стандартный new
'new', который вы переопределяете в своем классе - это 'operator new', т.е. функция выделения "сырой" памяти. Это лишь часть работы new-expression, которая выполняется до вызова конструктора. Перопределять вы ее можете сколько угодно, но на общий алгоритм работы new-expression этот никак не повлияет. Конструктор будет по прежнему вызываться после выделения памяти (т.е. после вызова вашего 'operator new') и отменять что-то в конструкторе уже поздно. Т.е можно только бросать исключения и эти исключения будут вылетать наружу.

Переопределить общий алгоритм работы самого new-expression невозможно. Это фундаментальное встроенное свойство языка.
1
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
27.10.2014, 19:54
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
т.е. функция выделения "сырой" памяти.
ну и ???
проверка на входе, т.е память еще не вызвана конструктор не сработал
условия соблюдены сразу выходим, дальше дело не пойдет
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
27.10.2014, 20:05
Цитата Сообщение от ValeryS Посмотреть сообщение
проверка на входе, т.е память еще не вызвана конструктор не сработал
условия соблюдены сразу выходим, дальше дело не пойдет
Проверка чего на входе?

Читайте постановку задачи: создание объекта требуется прервать именно из середины конструктора. Т.е. где-то в середине выполнения конструктора вы вдруг неожиданно натыкаетесь на какую-то проблему, решаете "а ну его нафиг, не получается нифига" и хотите прервать конструирование с возвратом null pointer из new.

Т.е. вся соль задачи стостоит в том, что заранее о предстоящих проблемах вы не знаете и/или не хотите знать. (Если бы знали, то и new бы вообще не делали.) Проблемы возникают условно-неожиданно в середине выполнения конструктора.

Как вам в этом поможет перегрузка 'operator new'???
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
27.10.2014, 20:11
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Проверка чего на входе?
как чего?
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
при определённых условиях
а какие условия, откуда я знаю
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Читайте постановку задачи: создание объекта требуется прервать именно из середины конструктора.
читаю
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
как можно отменить при определённых условиях создание экземпляра класса из конструктора, чтоб память под объект не выделилась и оператор new вернул бы nullptr.
задача чтобы не создался объект и не выделилась память !
принципиально что из конструктора?
если нет, то переопределенным new все решается
если да, то тут поплясать придется
а смысл?
можно конечно впихнуть
C++
1
delete this;
но головняков то это не уменьшит
а если еще и класс не в куче создается, как конструктор отследит?

Добавлено через 3 минуты
кстати у MickeyBlueEyes, похожий подход
правда new не переопределяет, но дело то до конструктора тоже не доходит
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
27.10.2014, 20:11
Цитата Сообщение от ValeryS Посмотреть сообщение
можно конечно впихнуть delete this;
А зачем? Во-первых, вернуть null из new-expression это не поможет. Во-вторых, если конструктор кинул исключение, то аналог вашего delete this будет выполнен автоматически внутри new-expression.
0
Заблокирован
27.10.2014, 20:13  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
принципиально что из конструктора?
да в принципе не принципиально
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
27.10.2014, 20:14
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Во-вторых, если конструктор кинул исключение,
Еще раз спрошу, класс создался не динамически, что делать с исключением?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
27.10.2014, 20:17
Цитата Сообщение от ValeryS Посмотреть сообщение
кстати у MickeyBlueEyes, похожий подход
правда new не переопределяет, но дело то до конструктора тоже не доходит
Это-то и плохо.

В рамках поставленной задачи правильнее было бы написать фабрику вида

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
static A* create() 
{
  A *a = NULL;
 
  try {
    p = new A;
  } 
  catch (...) {
     return NULL;
  }
  
  return a;
}
Добавлено через 2 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
Еще раз спрошу, класс создался не динамически, что делать с исключением?
Ничего не делать. Обрабатывать так, как вы считаете нужным.

Напомню, что вопрос именно и только о динамическом создании - хотят, чтобы new вернул null pointer. Никаких изменений в поведении нединамического создания никто не просил.
0
Заблокирован
27.10.2014, 20:17  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
можно переопределить new в своем классе который будет или не будет вызывать стандартный new
Я вот что - то не пойму, если я его переопределю и напишу A* a = new A, то стандартный new вообще не вызовется, вызовется только мой и в нём я уже определю, вызывать настоящий new или нет, так что ли? А в коде переопределения, когда условия все в порядке и я создаю объект и пишу return new A, сработает оригинальный new или опять же new класса и рекурсия завертится ? ))
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
27.10.2014, 20:23
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
и напишу A* a = new A, то стандартный new вообще не вызовется, вызовется только мой и в нём я уже определю, вызывать настоящий new или нет, так что ли?
по сути да
1
Заблокирован
27.10.2014, 20:42  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
по сути да
нее... переопределение оператора new - это оверхед по геморою Там придётся malloc-ами вручную память выделать, т.к. если в коде переопределения оператора new написать return new ... то вызовется опять же это переопределение )))))) Так что тут маллоки, короче то что в налаче говорил MickeyBlueEyes про - думаю оптимальный вариант, ему и лучший ответ , всё аукцион закончен
0
Модератор
Эксперт по электронике
8981 / 6748 / 921
Регистрация: 14.02.2011
Сообщений: 23,871
27.10.2014, 20:46
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
return new ...
ну во первых ::new
во вторых ничего там сложного
я сейчас могу сказать только теоретически, последний раз переопределял лет пять назад
вспомню опишу подробно
1
Заблокирован
27.10.2014, 20:48  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
вспомню опишу подробно
договорились...
А вообще изначально мне это нужно было для того, чтоб класс не мог создаваться без определённых входных данных, чтоб если допустим в конструктор вместо необходимого параметра передали ноль - то пошёл лесом как говориться
Чтоб как бы в начале каждой функции в классе не проверять, а передался ли обязательный параметр... и если он не валидный - функция выходит. То есть я как бы делаю запрет на создание объекта без обязательного валидного параметра (его валидность и есть условие создания объекта)
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
27.10.2014, 20:53
Цитата Сообщение от -THE_MASTER666- Посмотреть сообщение
Я вот что - то не пойму, если я его переопределю и напишу A* a = new A, то стандартный new вообще не вызовется, вызовется только мой и в нём я уже определю, вызывать настоящий new или нет, так что ли?
Вы сначала определитесь, что вы имеет в виду под new в данном случае.

Когда вы пишете 'A* a = new A', то вот это 'new A' называется new-expression. Алгоритм работы new-expression таков (упрощенно)

1. Выделить "сырую" память путем вызова функции 'operator new'
2. Сконструировать в этой памяти объект путем вызова конструктора
3. Если из конструктора вылетело исключение, то освободить память при помощи функции operator delete

Когда вы перкопределяете функцию 'operator new', вы перопределяете тольео первый шаг этого алгоритма. Все.

Поэтому не путайте функцию 'operator new' и все new-expression. Это разные вещи. Другими словами, когда вы пишете 'A* a = new A', то переопределить общее поведение вот этого 'new' невозможно. Вы можете переопределить лишь маленкий кусочек поведения new-expression, связанный с выделением сырой памяти под объект. Больше вы ничего переопередлить не можете. Поменять сам алгорим работы new-expression невозможно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.10.2014, 20:53
Помогаю со студенческими работами здесь

Удаление объекта класса в конструкторе
Приветствую, форумчане! Мне необходимо при определённых условиях возвращать из конструктора None вместо объекта. Атрибуты класса удаляю...

Можно ли для объекта определить оператор[] как в C#
Можно ли для объекта определить оператор как в C# class S { private int array; public int this { return array; } }

Добавление в вектор объекта класса в конструкторе
Почему у меня не получается сделать вот так? vector <C> Vec; class C { public:

Доступ к экземпляру объекта созданного в конструкторе через массив
Добрый день, Разбираю запутанный код, точнее создаю самостоятельно по шагам, код из другого проекта. Все конструкции и...

Метод в конструкторе вызывается задолго после создания объекта
Не знаю как загуглить это, поэтому обращаюсь к живым людям. Есть классы Group, Student, Subject. Group хранит вектор Student'ов, Student...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru