Существуют допустимые варианты использования, когда вы хотите выставить классы конструкторам. Если вы хотите выполнить собственное управление памятью, например, с помощью распределителя арены, вам потребуется двухфазная конструкция, состоящая из выделения и инициализации объекта.
Подход, который я использую, похож на подход многих других языков. Я просто помещаю свой код конструкции в общеизвестные общедоступные методы ( Construct () , init () , что-то в этом роде) и вызываю их напрямую, когда это необходимо.
Вы можете создавать перегрузки этих методов, которые соответствуют вашим конструкторам; Ваши обычные конструкторы просто вызывают их. Поместите большие комментарии в код, чтобы предупредить других о том, что вы делаете это, чтобы они не добавили важный строительный код в неправильное место.
Помните, что существует только один метод деструктора, независимо от того, какая перегрузка конструкции была использована, поэтому сделайте ваши деструкторы устойчивыми к неинициализированным элементам.
Я рекомендую не пытаться писать инициализаторы, которые могут переинициализироваться. Трудно сказать случай, когда вы смотрите на объект, в котором есть только мусор из-за неинициализированной памяти и фактического хранения реальных данных.
Наиболее сложная проблема возникает с классами, которые имеют виртуальные методы. В этом случае компилятор обычно подключает указатель таблицы функций vtable как скрытое поле в начале класса. Вы можете вручную инициализировать этот указатель, но в основном вы зависите от конкретного поведения компилятора, и ваши коллеги могут смотреть на вас забавно.
Размещение нового нарушено во многих отношениях; в построении / уничтожении массивов есть один случай, поэтому я склонен его не использовать.