【问题标题】:Returning a copy of an Object's self in C++在 C++ 中返回对象自身的副本
【发布时间】:2011-01-21 21:42:54
【问题描述】:

好的,所以我搜索了这个问题并搜索了堆栈溢出,但我似乎找不到一个好的答案。所以,我在这里问的是我的问题特有的问题。如果这是一个简单的答案,请很好,我是这门语言的新手。这是我的问题:

我正在尝试为重载运算符的 C++ 类编写方法。我想返回修改后的实例的副本,而不是实例本身。为了便于举例,我将使用BigInt 类来演示我遇到的问题。

如果我有以下代码:

const BigInt & operator+() const //returns a positive of the number
{
    BigInt returnValue = *this;  //this is where I THINK the problem is
    returnValue.makepositve();   //for examples sake
    return returnValue;
}

我收到返回值可能已在堆栈上创建的错误。我知道这意味着我必须在堆上创建对象并返回引用。但是如果我将 3rd 行更改为:

BigInt & returnValue = *this;

我收到一条错误消息,告诉我语法不正确。我不太确定该怎么做,非常感谢任何帮助!

【问题讨论】:

    标签: c++ reference return-value


    【解决方案1】:

    试试

    BigInt * returnValue = this;
    

    【讨论】:

    • 我试过了,但我得到的错误是:对非常量引用的初始值必须是左值
    • this 是一个指针,即BigInt*,不能分配给引用。
    【解决方案2】:

    我的 C++ 有点生疏了,但是呢:

    BigInt* returnValue = new BigInt(this)
    ...
    return *returnValue;
    

    【讨论】:

    • 它告诉我没有构造函数的实例与参数列表匹配。
    • 这种方法的问题是最终会导致内存泄漏。您将如何删除新创建的对象?此外,它将是 new BigInt(*this)
    【解决方案3】:

    问题在于您的函数签名。您确实必须返回整个对象,而不仅仅是一个引用。

    您的函数将如下所示

    BigInt operator+() const //returns a positive of the number
    {
        BigInt returnValue = *this;
        returnValue.makepositve();   //for examples sake
        return returnValue;
    }
    

    【讨论】:

    • 好的,那么如果我返回整个对象,是否需要在堆上创建对象?
    • 不,你可以在堆栈上创建它。
    • 不,c/c++ 将返回值从调用的堆栈帧复制到前一个。基本上这意味着,当您没有指针时,对象在返回时被复制。 (像指针这样的原语也会被“复制”,但你不会注意到,因为它们只是指向同一个对象。)
    【解决方案4】:

    你不妨把运算符的返回值设为BigInt。然后复制构造函数将在返回时自动发生:

    const BigInt operator+() const //returns a positive of the number
    {
        BigInt returnValue = *this;  //this is where I THINK the problem is
        returnValue.makepositve();   //for examples sake
        return returnValue;
    }
    

    现在看起来复制构造函数会发生两次,一次在运算符内部,另一次在函数返回时发生,但使用返回值优化,它实际上只会发生一次,因此在性能方面它已经达到了最好的水平。

    【讨论】:

      【解决方案5】:

      请注意,重载运算符应具有直观的语义。正如您在提供的示例代码中所做的那样,将一元 + 定义为“绝对值”,这让客户非常困惑。用户定义类型上的运算符的行为应该与内置类型上的一样。例如,+(-5) 产生 -5,而不是 +5。因此,operator+ 的实现应如下所示:

      BigInt& operator+() //returns the unchanged number
      {
          return *this;
      }
      
      const BigInt& operator+() const //returns the unchanged number
      {
          return *this;
      }
      

      如果你想提供一个绝对值函数,那么就这样做吧:

      BigInt abs(BigInt x)
      {
          x.makePositive();
          return x;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-24
        • 2023-03-16
        • 2012-06-25
        • 2020-01-18
        相关资源
        最近更新 更多