Создать объект минуя конструктор13.05.2026, 08:41. Показов 3685. Ответов 40
Метки нет (Все метки)
Добрый день
Опять долго нет никаких тем, даже глупых. Хорошо, вот слышал что можно создать объект минуя вызов его конструктора, хотя таковой имеется. Как-то через темплейт. Правда или нет - не знаю. Зачем нужно такое извращение - лично мне незачем, чисто спортивный интерес. На всякий случай конкретизируем вопрос
Спасибо
0
|
|||||||||||
| 13.05.2026, 08:41 | |
|
Ответы с готовыми решениями:
40
Создать класс "Вектор" и реализовать конструктор по умолчанию, конструктор копирования и деструктор
Для класса создать конструктор инициализации, конструктор копирования и преобразования типов, set |
|
1070 / 991 / 153
Регистрация: 10.08.2015
Сообщений: 5,413
|
|
| 16.05.2026, 10:46 | |
|
0
|
|
|
6312 / 3035 / 1053
Регистрация: 01.06.2021
Сообщений: 11,552
|
||
| 16.05.2026, 11:53 | ||
|
0
|
||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||||||||||||||||||||||||||||
| 16.05.2026, 21:13 | ||||||||||||||||||||||||||||||||
|
Конструктор - специальная функция-член класса, которая может: 1. Запускать конструктор базового класса. 2. Делегировать вызов другому конструктору. 3. Исполнять список инициализации. 4. Исполнять кастомную логику, описанную в теле конструктора. А ваше это - это только лишь 3 пункт. И кстати, конструктор не обязан его исполнять. Выше вам привели пример ситуации, когда данные-члены остались неинициализированными. Значение имеют правила языка с++, и алгоритм, который описал программист на этом языке. Например, программист может описать вызов ничего не делающей функции, а компилятор может оптимизировать этот вызов. Однако, оптимизация никак не отменяет факт наличия вызова функции в алгоритме, который описал программист. Формально (с точки зрения языка) в исходном коде описан вызов функции. Для примера рассмотрим такую ситуацию: программист разрабатывает статическую библиотеку. Он описал в глобальной области файла.cpp ничего не делающую функцию:
Объясняется это очень просто: функция определена. То есть, объективно она существует, и имеет внешнее связывание. В общем случае ни компилятор, ни линкер не могут предсказать, кто и как может вызвать такую функцию. Например, кто-то может слинковаться с библиотекой, срисовать адрес функции, и сделать вызов по указателю. А компилятор — не телепат, он понятия не имеет, что именно там может быть вызвано по указателю: пустышка, или не пустышка, поэтому ему ничего не остается, кроме как сгенерировать код для "честного" вызова функции. И если это окажется вызов ничего не делающей функции, значит это будет честный вызов ничего не делающей функции. Суть в том, что ставить знак равенства между конструктором и инициализаций — некорректно. Инициализация — это лишь часть того, что можно делать в конструкторе. Назначение конструктора заключается в том, что бы подготовить экземпляр класса к работе. После завершения этапа инициализации полей класса, наступает этап подготовительных действий. Что именно подразумевается под "подготовительными действиями" определяется программистами. Например, нужно залоггировать значения полей
В компилятор можно встроить, например, телеметрию какую-нибудь. Или поддержку каких-то дополнительных инструментов. Конструкторы — это часть языка, а не компилятора. У фундаментальных типов конструкторов не существует. Однако, существует синтаксический сахар, который весьма похож на вызов конструктора. Например, конструкции вида:
Более полный пример
Для классов компилятор действительно сгенерирует вызовы конструкторов. А для фундаментальных типов задействует "фиктивные конструкторы", которые и внешне, и по поведению похожи на настоящие. Словосочетание "фиктивные конструкторы" в кавычках, потому что это неофициальный термин. В различных источниках ещё можно встретить обозначение "псевдо-конструкторы", но это тоже неофициальный термин. Так же можно встретить понятие: "псевдо-конструкторы реализуются через Functional cast" И, что характерно, словосочетание Functional cast можно встретить даже в тексте стандарта, но от этого оно официальным термином не становится. Официально жеж
Фиктивные конструкторы реализуются через явное преобразование типов в функциональной нотации, которая называется Explicit type conversion (functional notation) Учитывая, что словосочетание functional cast notation упоминается с явной ссылкой на Explicit type conversion (functional notation), то вполне корректно полагать их синонимами. В свою очередь, правила Explicit type conversion (functional notation) ссылаются на общие правила инициализации 1. Для конструкций вида: t v1 = t{}; или t v1 = t(); — это Functional cast, который запускает Direct-initialization, который в свою очередь запускает Value-initialization 2. Для конструкции вида: t v2{}; или t v3{v}; — запуск List-initializationГде: - Для пустых скобок t v2{}; отрабатывает Value-initialization, - А для t v3{v}; отрабатывает Direct-list-initialization.3. Для конструкции вида: t v3(v); - это Direct-initialization4. Для конструкции вида: t v4; - это Default-initialization, которая для фундаментальных типов ничего не делает, поэтому значение такого объекта будет indeterminate value, чтение которого - Undefined BehaviorПро четвертый пункт см. ниже. Несмотря на то, что фиктивные конструкторы весьма похожи на настоящие, у них есть важное отличие, которое нужно иметь ввиду. Потому что иначе можно налететь на UB
Итого: 1. Строго говоря, конструктор может оставить экземпляр без инициализации. А так же может делать вещи, которые не связаны напрямую с инициализацией. Поэтому ставить знак равенства между конструктором и инициализацией принципиально некорректно. 2. У фундаментальных типов вообще нет конструкторов. 3. Можно считать, что у фундаментальных типов есть фиктивные конструкторы, но при этом важно понимать, что на самом деле представляют собой такие "фиктивные конструкторы", и каково принципиальное отличие от настоящих.
3
|
||||||||||||||||||||||||||||||||
|
332 / 126 / 8
Регистрация: 19.07.2024
Сообщений: 663
|
|||||
| 16.05.2026, 21:24 | |||||
![]() Если всё-таки не обязан и не исполняет ничего кроме 3-го пункта - он остаётся конструктором или нет? Если да, то тогда вы сами себе противоречите. Не замечаете? Вобщем - у вас явные проблемы с логикой. Раз компилятор оптимизировал (удалил) вызов пустой функции, значит этого вызова нет.Более того - компиляторы даже и могут и выкидывают не только пустые функции, но и не пустые, если результат их работы нигде не используется. Более того - это одна из главных задач компоновщика. Иначе любая программа включала бы все возможные функции, описанные в подключаемых библиотеках, и весила бы побольше полной винды. PS: Как видно - вы взялись рассуждать о том, о чём понятия не имеете. Да ещё и с логикой явные проблемы. Займитесь реально программированием, а не теоретизированиями с дивана, и узнаете и это и многое другое, новое и удивительное.
0
|
|||||
|
6312 / 3035 / 1053
Регистрация: 01.06.2021
Сообщений: 11,552
|
||
| 16.05.2026, 22:01 | ||
Это поведение называется Dead Code Elimination (DCE) - одна из стандартных оптимизаций, которую выполняет компилятор. GCC и Clang убирают неиспользуемые функции уже на уровне -O1. Причём если функция объявлена в единице трансляции без __attribute__((used)) или аналогов, компилятор вправе выбросить её полностью.Стоит оговориться: речь идёт о функциях с внутренней компоновкой (static) или шаблонах. Функции с внешней компоновкой (без static, в .cpp-файле) компилятор обычно сохраняет - их может вызвать другая единица трансляции. Но линковщик с включённым LTO (Link-Time Optimization) или флагом -ffunction-sections + --gc-sections уберёт и их, если они не используются нигде в программе.
0
|
||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||||||||||||||||||||||||||||||||||||
| 17.05.2026, 01:38 | ||||||||||||||||||||||||||||||||||||||||
|
Особенно учитывая, что я не давала вам повода для такого вопроса. Я нигде не писала, будто бы конструктор обязан выполнять 1, 2 и 4 пункты. Я использовала глагол: Вы бредите. Проверить очень просто: вы не сможете внятно обосновать, в чем именно заключается противоречие. Более того, сама постановка вашего вопроса: Однако, в с++ не существует условий при которых решается, останется ли конструктор конструктором, или не останется. Если конструктор — конструктор, то он — уже конструктор, и конструктором быть не перестанет. Интересны факты. Желательно, с примерами кода, и со ссылками на черновик стандарта с++. Процитирую для вас ещё раз: Тут одно из двух: либо вы - балабол, либо очередная невнимательность с вашей стороны. Процитирую на всякий случай сабж ещё раз: Из статической библиотеки в принципе нельзя выкидывать функции с внешним связыванием. Я ведь не просто так явным образом подчеркнула: Далее происходит следующее:
Ему придется сгенерировать честный вызов функции по указателю, а функция, соответственно, должна быть. Иначе код сломается. Линкер может выкинуть неиспользуемую функцию с внешним связыванием, но только если точно знает, что она не будет использована. Например, при сборке запускаемого (exe) приложения. Однако к статическим библиотекам это не относится, потому что линкер — не телепат, и не может знать заранее, какие именно функции статической библиотеки будут востребованы её клиентами. Так то, конечно, линкер может вырезать и из статической библиотеки тоже, но не сам, а только если его об этом явно попросить. Например, для gcc как то так
С помощью комбинации флага --gc-sections и частичной линковки -Wl,-r можно попросить линкер «вырезать» неиспользуемые функции до того, как код превратится в финальный архив библиотеки.Шаг 1: Сначала выполняем компиляцию в режиме "каждая функция в своей секции"
Вместо того чтобы отдавать файлы .o архиватору, нужно вызвать линкер с флагами частичной линковки, очистки, и явным указанием "корня".
Если просто запустить: -Wl,-r -Wl,--gc-sections, тогда линкер выдаст ошибку:
Ему нужно объяснить, что тут нужное, а что можно выкинуть. Для этого ему нужно указать корень графа вызовов. В обычном приложении таким корнем является функция main. Но в статическое библиотеке нужно указывать явно одним из возможных способов: 1. Флаг точки входа (задаёт один главный корень): -Wl,-e, my_public_api_function 2. Флаг принудительного удержания: -Wl,--undefined=my_public_api_function 3. Специальный файл (линкер-скрипт), где перечислены все публичные функции. (это самый частый подход для больших библиотек). Итого: Если указать линкеру, какие функции статической библиотеки являются публичными, тогда при запуске -Wl,-r -Wl,--gc-sections он построит от них граф зависимостей, и вырежет всё лишнее, что не используется внутри самой библиотеки, и на выходе выдаст чистый .o файл для упаковки в .a.Но автоматически, без подсказок со стороны программистов он такое делать не будет. Ни LTO, ни отдельно взятые флаги -ffunction-sections, --gc-sections не заставят линкер вырезать функцию, в ситуации, когда он не знает, а вдруг она кому то нужна. А у вас только голословное балабольство без какой либо конкретики.
1
|
||||||||||||||||||||||||||||||||||||||||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
||||||
| 18.05.2026, 03:15 | ||||||
|
Значит можно использовать std::bit_cast Кроме того, он является Implicit-lifetime type Значит можно использовать std::malloc, и std::start_lifetime_as В с++ "создать объект" — значит запустить время его жизни. Запускать время жизни объектов могут не только конструкторы, но и специально уполномоченные стандартные функции. Например: - std::malloc, std::calloc, std::realloc, std::memcpy, std::memmove, - std::bit_cast, allocate у стандартных аллокаторов, - std::start_lifetime_as, std::start_lifetime_as_array Может быть ещё какие то имеются, или появятся. Суть в том, что если стандарт наделяет некоторую функцию полномочиями создавать объекты, то он явным образом это регламентирует. При этом стандарт четко регламентирует ограничения. Например, для std::malloc ограничение: объекты должны быть Implicit-lifetime type Детали
1. c.malloc неявно создает объекты по правилам intro.object, 2. Которые в свою очередь ссылаются на basic.types.general 3. Которые в свою очередь ссылаются на class.prop 4. Которые уже непосредственно определяют, какие классы обладают свойством implicit-lifetime
Примечание: выражение new (и new[]) тоже относят к уполномоченным создавать объекты. Но в действительности new лишь инициируют процедуру создания, а дальше работает конструктор. Уже 6 лет прошло с выхода с++20, в котором был принят Defect Report группы Ричарда Смита (P0593R6) Статус Defect Report означает, что комитет признал старые правила ошибочными. См. пункт 4
Собственно, именно по итогам P0593R6, в с++20 добавили Implicit-lifetime types, которое ознаменовало собой завершение вопиюще ханжеского безобразия: с++ наконец то признал сишное подмножество легальным. Понадобилось всего каких то 22 года.
5
|
||||||
|
2689 / 1346 / 485
Регистрация: 08.11.2016
Сообщений: 3,734
|
|||
| 18.05.2026, 09:41 | |||
|
0
|
|||
| 18.05.2026, 17:17 [ТС] | ||||||||||||
). Вот чисто практическая задачкаЕсть ф-ция вызываемая сотни (и больше) раз
0
|
||||||||||||
|
2689 / 1346 / 485
Регистрация: 08.11.2016
Сообщений: 3,734
|
|||||||
| 19.05.2026, 10:36 | |||||||
0
|
|||||||
|
332 / 126 / 8
Регистрация: 19.07.2024
Сообщений: 663
|
|||||||
| 20.05.2026, 11:30 | |||||||
|
Хамите своему мужу на кухне. Ку? Обосновал? Дошло??? Так достаточно внятно, или нужно разжёвывать ещё доступнее? Ещё раз напоминаю, что в данной теме обсуждается инициализация объекта и как она отличается от конструктора объекта. Если конструктор - пустая функция (типа изображённой вами выше) или функция не имеющая никакого полезного результата, то компилятор вправе полностью выкинуть её. И никакие "статические библиотеки" к делу не относятся - не нужно накидывать на вентилятор! Пока вы приводили только не относящийся к делу мусор. Сможете? Или способны только хамить с дивана?
0
|
|||||||
|
2689 / 1346 / 485
Регистрация: 08.11.2016
Сообщений: 3,734
|
|||||||||||
| 21.05.2026, 09:32 | |||||||||||
|
Igor3D, самый простой вариант: объявить пустой класс с говорящим именем, сделать каждый тип который предполагается сохранять таким образом его наследником и в ассерте (или в концепте) проверять является ли подставляемый тип наследником этого служебного класса.
0
|
|||||||||||
| 21.05.2026, 19:28 [ТС] | ||
|
Не уловил чего Вы хотели достичь "финализацией"?
0
|
||
|
2689 / 1346 / 485
Регистрация: 08.11.2016
Сообщений: 3,734
|
|||||
| 21.05.2026, 19:55 | |||||
|
0
|
|||||
| 21.05.2026, 20:17 [ТС] | ||
|
Ну хорошо, а отловить член-указатель - никак?
0
|
||
|
2689 / 1346 / 485
Регистрация: 08.11.2016
Сообщений: 3,734
|
|||
| 21.05.2026, 20:41 | |||
std::is_pointer<T> который скажет указатель это или нет, но чтобы его применить для такой задачи надо как-то разложить класс на поля и как-то по ним пройтись, а в плюсах с рефлексиями туго, почти уверен что сделать можно, но выглядеть это будет как коричневая магия.
0
|
|||
|
16 / 12 / 3
Регистрация: 01.10.2023
Сообщений: 106
|
||||||||
| 22.05.2026, 03:03 | ||||||||
|
Кликните здесь для просмотра всего текста
0
|
||||||||
|
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
|
|||||||||||||||||||||||||||
| 23.05.2026, 00:57 | |||||||||||||||||||||||||||
|
Например, вот так можно пробежаться по всем полям произвольной структуры, и вывести их имена и значения: (Актуально для любителей сериализаторы колхозить)
А ещё, теперь можно легально проверить тип на полноту, без риска налететь на UB
Но де-юре, код использующий трюк с consteval все равно Ill-formed, no diagnostic required, что по сути является UB Но поскольку все инстансы, и прочие компалтайм вычисления, которые порождаются в процессе работы consteval, должны быть аннигилированы по факту её завершения, то технически нарушения ODR не возникает (ед. трансляции не порождают конфликтующих символов для линкера). В некотором смысле, рефлексия просто узаконила подобные трюки. Появилось новое понятие: Evaluation Context Конечно, само по себе понятие manifestly constant-evaluated context и раньше было, но в с++26 его радикально пересмотрели. Раньше контекст определял только "мы в рантайме" или "мы времени компиляции". Новый контекст теперь содержит "состояние компалтайм-вычислений здесь и сейчас". Теперь можно выстраивать логику по принципу "сейчас состояние кодовой базы одно, а на следующем шаге оно может стать другим" Пример:
Вывод в консоль:
3
|
|||||||||||||||||||||||||||
|
Вездепух
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
|
|||||||
| 29.05.2026, 23:49 | |||||||
S есть конструкторы: конструктор по умолчанию и конструктор копирования. Однако в данном примере объект инициализируется при помощи агрегатной инициализации, которая не использует никаких конструкторов.
0
|
|||||||
| 29.05.2026, 23:49 | |
|
Передача файлов от клиента к клиенту, минуя сервер(как в icq).
Перевод из одной системы счисления в другую, минуя десятичную Как побитово скопировать uint32_t в float, минуя при этом выделения uint32_t в оперативную память Создать объект стек и создать объект очередь с перегруженными операциями Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров
В текущей версии модели успешно реализован ключевой механизм. . .
|
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям
Реализованные компоненты:
Механизм закисления почвы через протонную помпу
Конкуренция между типами микориз
pH как триггер сукцессии
C/ P соотношение. . .
|
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
|
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
|
|
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы
## О чём эта статья
В процессе построения ОДУ-модели (система дифференциальных. . .
|
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет)
Содержание проекта
Симуляция вековой (50 лет) экологической сукцессии в почве леса
Основные участники: АМ-гриб, ЭКМ-гриб,. . .
|
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов
Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
|
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация
В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
|