【问题标题】:chaining method of same object同一对象的链接方法
【发布时间】:2017-10-18 01:20:15
【问题描述】:

我现在正在上课

但是调用方法链有问题(这里是代码

class Point{
public:
    int x;
    int y;
    Point(int i , int j);
    Point incrementX();
    Point incrementY();
    void print();
};
Point::Point(int i, int j){
    x = i;
    y = j;
}
Point Point::incrementX(){
    x++;
    return(*this);
}
Point Point::incrementY(){
    y++;
    return(*this);
}
void Point::print(){
    cout << "(" << x << "," << y << ")" << endl;
}

void Q11(){
    Point a(2,3);
    //(3,4)
    a.incrementX().incrementY().print();
    //(3,3)why 33 here ??
    a.print();
}

我很困惑为什么最后一个代码a.print() 给出了(3,3)

我尝试在方法中打印出this的地址

我在调用incrementX()incrementY()时发现这两个地址不同

我的猜测是incrementX()访问了类,但是调用incrementY()时类被占用了。所以它会在堆中复制类,然后incrementY() 更改副本中的 y...

所以(3,4) 是通过副本打印的,(3,3) 是通过实际类打印的...

【问题讨论】:

    标签: c++ chaining


    【解决方案1】:

    只有a.incrementX() 增加成员值。 a.incrementX().incrementY()增加一个临时实例化并被丢弃。

    Point Point::incrementX()函数中用Point&amp;替换Point,你会得到正确的结果。

    【讨论】:

      【解决方案2】:

      您的 incrementXincrementY 函数按值返回。也就是说,在从这些函数返回时,您的对象会被复制,因此后续操作会发生在不同的实例上。

      如果您删除复制构造函数,您可能会在编译中看到错误。为此添加

      Point(const Point&) = delete;
      

      (假设 c++11 或更高版本使用 delete。如果较旧,则将其设为私有)

      所以要诊断你的实际错误:

      1. 您使用值 (2, 3) 构造 Point
      2. incrementX 的第一次调用在您的原始实例(现在是值(3,3))上运行,并在返回时传递一个副本。
      3. incrementY 对临时副本进行操作并将其值更新为 (3, 4)。它还会返回一个副本。
      4. 您打印第二份临时副本,得到预期结果 (3,4)。
      5. 现在a.print() 会显示您的原始Point,它在调用incrementX 后就没有被触摸过,并且显示为(3,3)。

      为了使用您希望使用的链接,您的所有操作都应该发生在 同一个 对象上,并实现您应该通过非 const 从这些函数返回参考

      函数签名

      Point Point::incrementX()
      

      变成

      Point& Point::incrementX()
      

      完整的代码如下。

      #include <iostream>
      using namespace std;
      
      class Point{
      public:
          int x;
          int y;
          Point(int i , int j);
          //Point(const Point&) = delete;
          Point& incrementX();
          Point& incrementY();
          void print();
      };
      Point::Point(int i, int j){
          x = i;
          y = j;
      }
      Point& Point::incrementX(){
          x++;
          return(*this);
      }
      Point& Point::incrementY(){
          y++;
          return(*this);
      }
      void Point::print(){
          cout << "(" << x << "," << y << ")" << endl;
      }
      
      int main(){
          Point a(2,3);
          a.incrementX().incrementY().print();
          a.print();
      }
      

      使用删除的复制构造函数,这段代码编译得很好,因为没有复制发生。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多