【问题标题】:C++ Trouble Overloading Operators - Class AssignmentC++ 重载运算符的麻烦 - 类分配
【发布时间】:2014-03-26 20:37:01
【问题描述】:

我在 stackoverflow 上查看了多个主题,但我对这个课程作业没有任何收获。我相信我正在使用书中介绍的代码,但是我遇到了 = 运算符不复制和 - 运算符返回两个连接的值的问题。我希望你能帮助我理解并指出我正确的方向。任何帮助表示赞赏。

rectangleType 类有两个受保护的成员,length 和 width,以及一个将它们相乘的名为 rectangleType.area() 的函数。在作业中,我应该更改返回长度和宽度以及返回区域的书籍代码,但我无法让这些正常工作。 (关系和流运算符工作正常。)

来自 rectangleType.h:

rectangleType operator=(const rectangleType&) const; // replace one rectangle with another
rectangleType operator-(const rectangleType&) const; // subtract one rectangle from another

来自 rectangleTypeImp.cpp

rectangleType rectangleType::operator=(const rectangleType& rectangle) const
{
    rectangleType temp = *this;

    temp.length = rectangle.length;
    temp.width = rectangle.width;

    return temp;
}
rectangleType rectangleType::operator-(const rectangleType& rectangle) const
{
    rectangleType temp = *this;

    if(temp.length - rectangle.length >= 1 && temp.width - rectangle.width >= 1)
    {
        temp.length = temp.length - rectangle.length;
        temp.width = temp.width - rectangle.width;

        return temp;
    }
    else
    {
        cout << endl << "Dimensions are not large enough."
             << "Cancelling operation and returning dimensions"
             << "of left operand." << endl;
    }

    return temp;    
}

在主文件中,我创建了以下对象:

rectangleType myOtherYard(26, 19);
rectangleType myBrothersYard(2, 2);
rectangleType myMothersYard(3, 3);

并编写了这段代码:

myOtherYard = myBrothersYard;
cout << endl << "myOtherYard = myBrothersYard: " 
     << myOtherYard;
cout << endl << "myBrothersYard - myMothersYard: " 
     << myBrothersYard + myMothersYard;

这是我得到的输出(使用格式化打印):

myOtherYard = myBrothersYard:   26.0019.00 
myBrothersYard - myMothersYard: 3.003.00

看起来 = 运算符中没有进行赋值,它返回第一个对象的长度和宽度而没有变化。此外, - 运算符似乎正在做它的工作,但分别返回长度和宽度,我不知道如何让它返回该区域。我在代码中尝试的一切都失败了。

+ 运算符添加并返回单独的长度和宽度值。看起来它确实正确地添加了它们。

您有什么方法可以帮助我了解如何解决这个问题?

【问题讨论】:

  • 查看operator= 的实现,您并没有更改“接收”端的对象,而是更改并返回一个临时对象。这是不正确的。 (另外,operator= 不应该是 const,因为本质上会改变对象!)。
  • 是的,我开始使用 temp 因为我无法让 length = rectangle.length 和 width = rectangle.width 工作。惊人的!我通过删除 const、删除 temp 并返回 *this!谢谢!
  • “不工作”是什么意思?
  • 它不会分配值,但现在可以。现在,我只需要弄清楚如何让它返回区域而不是单独的长度和宽度。 :-)
  • 不要在一个函数中使用两次endl。这意味着'\n' 然后是std::flush,所以只需将'\n' 放在不需要刷新输出的地方。

标签: c++ operator-overloading


【解决方案1】:

首先,您的赋值操作应该返回对您自己的引用。它也不应该是 const ,因为您正在分配给自己。请参阅许多参考资料,主要是 Scott Meyers “Effective C++”,以进行推理。

由于您只是在学习,而我在其中看不到它,因此我假设您不应该了解移动语义,因此我将其省略...

另一个矩形的赋值运算符...

rectangleType &
rectangleType::
operator=(rectangleType const & that)
{
    length = that.length;
    width = that.width;

    return *this;
}

但是,看起来默认的赋值运算符就足够了。如果你需要为类编写赋值运算符,我想你也必须编写复制构造函数。

如果您要拥有operator-,您还应该拥有operator-=。同样,请咨询 Meyers 以获得大量解释。

关于你的减法实现...... Egads。真的吗? cout 错误?然后返回一个不是正确答案的对象?

【讨论】:

  • 谢谢!你是对的,我不知道移动语义。我忘了做一个 -= 运算符,但是一旦我把它理顺了,它应该很容易做到。感谢您提到这一点,我也会这样做 += 。在我的减法实施中,我认罪,但请您原谅。 Malik 的示例返回的文本与我正在处理的对象中的数据无关,并且任务要求您返回错误消息。 :-)
  • 我已经修复了大部分问题。现在,我只是想不通为什么当我返回该区域时,我的乘法和除法运算符(使用相同的代码但更改为 * 和 /)没有给出正确的结果。 (叹气)要学的东西太多了!感谢您的帮助!
  • 我不介意帮忙做作业,如果它被标记为这样的话。您应该实现+= 等,然后根据它实现运算符。实际上很难想象矩形的相加和相减,但更难想象矩形的相乘和相除应该是什么。也许你想乘以一个标量而不是另一个矩形。此外,抛出异常是一种很好的表达方式:“你要求我做一些不可能的事情,我什至无法返回一个合理的值。:
  • 感谢您的建议。作为一个非传统的(读作:年长的)大学生,我意识到让别人为你做作业会剥夺你的学习经验。我尽量小心,只有当我真的被困住时才带着作业来这里,比如这次,或者只是需要一些建议。 :-)
【解决方案2】:

类似的东西可能会有所帮助:

rectangleType& rectangleType::operator=(const rectangleType& rectangle) 
{
    if (this != &rectangle)
    {
         length = rectangle.length;
         width = rectangle.width;
    }

    return *this;
}

【讨论】:

  • 我一直认为自分配检查是没用的。考虑有人这样做的情况。很少。当然,这种观点可以被视为主观的。
  • 我想知道这一点。我想我也对代码感到绝望,因为我没有意识到 const 是我最大的问题。我现在正在改变它,事情开始起作用了。 :-)
  • 现在好多了!感谢您的帮助!只是想弄清楚为什么 * 和 / 重载使用相同的代码作为基础没有给出预期的结果。你会认为 length = length / rectangle.length 和对 width 做同样的事情会导致返回的长度 * 宽度的区域,但它的行为很不稳定。 (叹气)要学的东西太多了!我很高兴我喜欢这个!
  • 自赋值检查在这里可能没用,但在更复杂的场景中它可能有助于防止重叠的内存复制。我会将此检查视为模式的一部分...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多