“具有”Point 类成员数据的 Rectangle 类。使用 Point 类的成员函数时,成员数据不会更新

Posted

技术标签:

【中文标题】“具有”Point 类成员数据的 Rectangle 类。使用 Point 类的成员函数时,成员数据不会更新【英文标题】:Rectangle Class that "has-a" Point class member data. Member data will not update when using Point class's member functions 【发布时间】:2013-12-05 22:23:05 【问题描述】:

Noobie 在这里玩耍!我创建了一个具有两个成员变量的 Rectangle 类: 点 ur 和点 ll(ur 是矩形的右上角,ll 是矩形的左下点)。 Point 是一个具有成员变量 Fraction X 和 Fraction Y 的类。 Fraction 是一个具有成员变量 num 和 denom 的类。所有这些变量都在其相应的类中受到保护。

创建 Rectangle 对象非常简单,但是一旦我尝试使用 Point 类中的成员函数移动这些点,Rectangle 对象的 X 和 Y 值不会更新,但函数内部的值会更新。

这是 Rectangle 类的头文件:

   class Rectangle 
   public:
     Rectangle () : ur(), ll() 
     
     ~Rectangle () 
     
     Rectangle (const Rectangle *);
     Rectangle (const Point&, const Point&);
     Rectangle & operator=(const Rectangle &);

     Rectangle compareArea(const Rectangle *) const;
     Rectangle compareVolume(const Rectangle *) const;

     Point getUR(void) const;
     Point getLL(void) const;

     void print(const Rectangle *) const;

  protected:
    Point ur;
    Point ll;
  ;

还有我的 Point 类:

 class Point 
 public:
   Point() : x(), y() 
   // Default const
   ~Point() 
   // Destructor
   Point(const Point&); // Copy const
   Point(const Fraction&, const Fraction&);
   Point& operator=(const Point&); // Assignment

   void moveBy(const Fraction&, const Fraction&);
   void moveBy(int);
   void flipByX(void);
   void flipByY(void);
   void flipThroughOrigin(void);
   void print(void);

   Fraction getX(void) const;
   Fraction getY(void) const;

 protected:
   Fraction x; // x-coordinate of the point
   Fraction y; // y-coordinate of the point
 ;

Point 类的“移动”成员函数之一如下所示:

void Point::moveBy(const Fraction& dx, const Fraction& dy) 

  x += dx; // Overloaded all comparison/ arithmetic operators in basic Fraction class
  y += dy;

我需要通过声明一个设置为 null 的 Rectangle 指针来创建 Rectangle 对象,直到用户决定创建两个 Rectangle 对象。

一切运行良好,用户输入的值已正确存储。

但是,当我尝试使用 Point 中的成员函数移动 Rectangle 类中的右上角(Point ur)和左下角(Point ll)点时,Point ur 和 Point ll 的 Fraction x 和 Fraction y 的值没有更新。

这是因为我的“get”方法是 const 吗?

我是这样称呼“移动”方法的:

Rectangle* r1 = new Rectangle(xC, yC);   // Assume xC and yC are proper fraction                 coordinates for X and Y

// Move now after user chooses some options in a menu

r1->getUR().getX().moveBy(Fraction(xNew, yNew), Fraction(xNew, yNew)); // Assume xNew, yNew are valid Fractions that the user has chosen to move his Points by...

这些值不反映(不更新也不存储)。当我打印坐标点时,我得到了原始的 xC 和 yC 值。我究竟做错了什么? (我需要以这种方式创建我的代码。不能使用智能指针、向量等。)如果您想查看我的其余代码以确定我做错了什么,我会尽快发布。

【问题讨论】:

是的,也有。这不是 Java。 :P 除非您需要将变量的作用域与对象的生命周期解耦,否则请坚持使用实际对象而不是指针,并利用自动销毁。总体而言,您的生活会轻松很多。 补充:什么是“分数” - 问题不完整。 【参考方案1】:

问题出在你的吸气剂上——但这与它们是const 无关。 (const,实际上,表示对象未被修改。从技术上讲,这意味着可以在const 对象上调用成员函数,this 的类型是const Class*,而不是Class*。 )

问题是它们返回对象:

Fraction getX(void) const;

也就是说,全新的对象。实际成员的副本。你想返回参考:

Fraction& getX();

如果你需要一个 const 版本:

const Fraction& getX() const;

【讨论】:

在这种情况下,如果他想通过非常量 Point::moveBy() 更改该点,他几乎无法返回 const Point&。 @JanKorous 好点。我交换了 const 和非 const 版本,与问题相关的版本现在位于顶部。 我不敢相信我忘记了这一点。谢谢!【参考方案2】:

由于它通过值而不是通过引用或指针返回一个对象,getUR() 返回其中Point副本。对副本的更改不会影响原件。

如果您希望能够以这种方式修改矩形的角,您需要让它返回一个引用或指针。

不过,更安全的方法是让 Rectangle 类本身进行所需的更改。这样您就可以控制类的内部细节,并且此类的用户不必担心在对象死亡后使用它们可能会打开虫洞的指针/引用。

【讨论】:

【参考方案3】:

可能还有更多问题:

一个。我不确定你是否应该这样称呼它

r1->getUR().moveBy(Fraction(xNew, yNew), Fraction(xNew, yNew));

b.真正的问题是您按值返回,而不是通过 Rectangle::getUR() 的引用返回,因此您在与您想要的完全不同的对象上调用 moveBy()。如果这不是一些愚蠢的错误,并且您没有立即得到它,我建议您阅读一些有关 C++ 参考的内容。

【讨论】:

以上是关于“具有”Point 类成员数据的 Rectangle 类。使用 Point 类的成员函数时,成员数据不会更新的主要内容,如果未能解决你的问题,请参考以下文章

Problem E: 点在圆内吗?

实验三

在 C++ 中创建具有 2 个双精度值的类

在C ++中用2个double值创建一个类

Java练习 SDUT-2670_3-1 Point类的构造函数

Boolan 第三周笔记