Использование метода цепочки в продолжении копирования конструктора / инициализации в одной декларации операторов в C++?

Как вы знаете, мы обычно используем возврат по ссылке для цепочки методов, я использую возврат по ссылке в первом коде, а результат - как я и предсказывал. Во втором блоке кода, когда я не использовал возврат по ссылке, цепочка была разорвана, и ожидаемый результат не был сгенерирован, но в третьем блоке кода я достиг желаемого результата, используя метод цепочки в продолжение копии Конструктор / инициализация в одной декларации операторов (без использования возврата по ссылке), вопрос в том, какова логика третьего кода, который защищает цепочку от взлома?

class Calc
{
private:
    int m_value;

public:
    Calc(int value = 0) : m_value{ value } {}

    Calc& add(int value) { m_value += value; return *this; }
    Calc& sub(int value) { m_value -= value; return *this; }
    Calc& mult(int value) { m_value *= value; return *this; }

    int getValue() { return m_value; }
};

int main()
{
    Calc calc;
    calc.add(5).sub(3).mult(4); // its OK and output 8

    std::cout << calc.getValue() << '\n';
    return 0;
}

class Calc
{
private:
    int m_value;

public:
    Calc(int value = 0) : m_value{ value } {}

    Calc add(int value) { m_value += value; return *this; }
    Calc sub(int value) { m_value -= value; return *this; }
    Calc mult(int value) { m_value *= value; return *this; }

    int getValue() { return m_value; }
};

int main()
{
    Calc calc;
    calc.add(5).sub(3).mult(4); // its NOT OK and output 5

    std::cout << calc.getValue() << '\n';
    return 0;
}

class Calc
{
private:
    int m_value;

public:
    Calc(int value = 0) : m_value{ value } {}

    Calc add(int value) { m_value += value; return *this; }
    Calc sub(int value) { m_value -= value; return *this; }
    Calc mult(int value) { m_value *= value; return *this; }

    int getValue() { return m_value; }
};

int main()
{
    Calc calc = Calc{0} // copy constructor / initialization
        .add(5) // method chaining
        .sub(3) // method chaining
        .mult(4); // method chaining, its OK and output 8

    std::cout << calc.getValue() << '\n';
    return 0;
}

1 ответ

Решение

Какова логика третьего кода, который защищает цепь от взлома?

Цепочка действительно получает разрыв, но вы используете конечный результат для присвоения calc

Calc calc = Calc{0}.add(5).sub(3).mult(4);

эквивалентно

Calc calc = Calc{2}.mult(4);

Что в конечном итоге получает копию, встроенную в calc временный Calc объект при умножении на 4,

Другие вопросы по тегам