Не думаю, что у вас есть большой выбор.
Если вы получили неверный ввод, вы не можете сделать больше, чем сообщить вызывающему, чем он неверен. Затем вы можете использовать код исключения или ошибки.
Код ошибки в конструкторе необходимо будет передать в качестве ссылочного параметра, и поэтому он будет выглядеть очень неудобно.
Вы можете попытаться найти способ проверить входные данные в источнике. Почему вы получаете неверные данные? Как ввод может быть неверным и т. Д.
Примером вашего класса дат будет принуждение пользователя (пользователя вашей программы) вводить только действительную дату (например, принудительно вводя ее в графическом интерфейсе типа календаря).
Вы также можете попытаться создать метод в своем классе для обработки проверки ввода.
При этом пользователь (на этот раз программист) может либо вызвать его до конструирования, и быть уверенным, что вызов не потерпит неудачу, либо откатится на исключение, если пользователь не проверил его.
Если производительность важна и вы не хотите вызывать функцию validate дважды (пользователь вызывает ее, затем в конструкторе), я думаю, вы могли бы использовать именованный конструктор idiom, чтобы иметь CheckedConstructor и UncheckedConstructor.
Хотя, думаю, это начинает переусердствовать в архитектуре.
В конце концов, это будет зависеть от класса и варианта использования.