Как вы знаете, мы обычно используем возврат по ссылке для цепочки методов, я использую возврат по ссылке в первом коде, а результат — как я и предсказывал. Во втором блоке кода, когда я не использовал возврат по ссылке, цепочка была разорвана, и ожидаемый результат не был сгенерирован, но в третьем блоке кода я достиг желаемого результата, используя метод цепочки в продолжение копии Конструктор / инициализация в одной декларации операторов (без использования возврата по ссылке), вопрос в том, какова логика третьего кода, который защищает цепочку от взлома?
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;
}
Какова логика третьего кода, который защищает цепь от взлома?
Цепочка действительно получает разрыв, но вы используете конечный результат для присвоения calc
Calc calc = Calc{0}.add(5).sub(3).mult(4);
эквивалентно
Calc calc = Calc{2}.mult(4);
Что в конечном итоге получает копию, встроенную в calc
временный Calc
объект при умножении на 4
,
Других решений пока нет …