Да, вы можете определить один конструктор в терминах другого. Нет, я не думаю, что вы можете сделать это без какой-либо дополнительной функции.
Конструктор, который вызывает другой конструктор того же класса, называется " делегирующий конструктор " и использует тот же своего рода синтаксис в виде списка инициализатора члена, но с использованием собственного имени класса вместо его базовых классов и членов:
ClassName::ClassName(SomeParam1 p1, SomeParam2 p2)
: ClassName(arg_expr1, arg_expr2, arg_expr3)
{ /* any other logic after the target constructor finishes */ }
Но этот случай немного сложен из-за необходимости в промежуточном объекте date_as_struct
, Или с обновленным вопросом, просто нужно сделать какой-то анализ перед входом в другой конструктор. Я бы решил эту проблему, сделав дополнительный приватный конструктор, который принимает Date_as_struct
:
class Date {
public:
explicit Date(int day = 1, int month = 1, int year = 0);
explicit Date(const string &date_as_string);
/* ... */
private:
struct Date_as_struct {
int day;
int month;
int year;
};
explicit Date(const Date_as_struct&);
static Date_as_struct ParseStringContainingDate(const std::string&);
};
Date_as_struct
и ParseStringContainingDate
, объявленные здесь как частные, так как похоже, что больше никто не будет использовать их.
Тогда для строкового конструктора у вас просто есть
Date::Date(const std::string& date_as_string)
: Date(ParseStringContainingDate(date_as_string))
{}
. Конструктор Date(const Date_as_struct&)
может очень легко делегировать Date(int, int, int)
или наоборот, в зависимости от того, что более естественно для фактического инициализация члена.