Неправильное значение напечатано при реализации методов цепочки - PullRequest
3 голосов
/ 26 марта 2019

Мне дано конкретное основное

int main() {

  Widget w;

  w.set(3).print().set(2).print();

  w.print();
}

и я должен написать виджет класса, такой, чтобы программа печатала 3,2,2.

Моя лучшая попытка Софар печатает неутешительные 3,2,3: /

class Widget{
public:
  Widget(){m_i =0;};

  Widget(int i){m_i =i;};

  Widget set(int i){
    this->m_i = i;
    return *this;
    };

  Widget print(){
    std::cout<<this->m_i<<std::endl;
    return *this;
    };
  int m_i;
};

int main() {

  Widget w;

  w.set(3).print().set(2).print();

  w.print();
}

есть идеи, как это решить? Спасибо всем, кто готов дать несколько советов:)

Ответы [ 3 ]

3 голосов
/ 26 марта 2019

Вам не хватает того, что объект, возвращаемый вашими функциями, должен быть ссылкой, например Widget&, а не Widget. В настоящее время вы возвращаете совершенно новую копию из каждого вызова set () или print (), что означает, что любые дальнейшие изменения этого объекта никогда не применяются к исходному w объекту.

1 голос
/ 26 марта 2019

Это происходит потому, что вы оставляете оригинал w без изменений после первого вызова set.

Это происходит потому, что вы копируете w при каждом возврате каждой операции:

Widget set(int i){
    this->m_i = i;
    return *this; // Copy, return type is a `Widget` value
}

Вместо этого вы должны вернуться по ссылке:

//    v--- There
Widget& set(int i){
    this->m_i = i;
    return *this; // No copy, return type is a `Widget` reference
}

Не копирование переменной виджета приведет к мутации w вместо временных копий.

0 голосов
/ 26 марта 2019

Вот в чем дело: и set, и print должны возвращать *this по ссылке. Добавление этого в (замена Widget на Widget&) и некоторые другие мелкие исправления делают свое дело:

#include <iostream>

class Widget{
public:
  Widget(int m) // Initialization over assignment
  : m_i(m)
  { }

  Widget()      // Initialization over assignment
  : m_i(0)
  { }

  Widget& set(int i) // return a reference 
  {
    m_i = i;         // this-> is not recommended
    return *this;
  };

  Widget& print()    // return a reference 
  {
    std::cout<< m_i << std::endl; // this-> is not recommended
    return *this;
  };

private: // data members are usually private
  int m_i;
};

int main() {

  Widget w;
  w.set(3).print().set(2).print().print();

  return 0;
}

Но реально вы бы объявили print как функцию const, потому что имеет смысл иметь возможность печатать объект const

...