Вызов конструктора с другими типами аргументов из другого конструктора в C ++ 17 - PullRequest
1 голос
/ 06 января 2020

У меня есть класс с именем Date:

class Date {
public:
    explicit Date(const int day = 1, const int month = 1, const int year = 0) {
        this->Construct(day, month, year);
    }

    explicit Date(const string &date_as_string) {
        int day, month, year;
        // parsing the string date_as_string
        this->Construct(day, month, year);
    }

private:
    void Construct(const int day, const int month, const int year) {
        // constructing the Date object
    }
};

Есть ли способ вызывать Date (int, int, int) непосредственно из Date (string &), что позволяет избежать написания отдельной функции?

UPD:

Некоторые пояснения. Мой класс должен выглядеть так:

class Date {
public:
    explicit Date(const int day = 1, const int month = 1, const int year = 0) {
        // constructing the Date object
    }

    explicit Date(const string &date_as_string) {
        int day, month, year;
        // parsing the string date_as_string
        // call Date(day, month, year) to construct the Date object
    }

  // any other functions

private:
    // private fields
};

И следующий код должен компилироваться:

Date date("some_string_containing_date");
Date date(1, 1, 0);

1 Ответ

2 голосов
/ 06 января 2020

Да, вы можете определить один конструктор в терминах другого. Нет, я не думаю, что вы можете сделать это без какой-либо дополнительной функции.

Конструктор, который вызывает другой конструктор того же класса, называется " делегирующий конструктор " и использует тот же своего рода синтаксис в виде списка инициализатора члена, но с использованием собственного имени класса вместо его базовых классов и членов:

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) или наоборот, в зависимости от того, что более естественно для фактического инициализация члена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...