代码之家  ›  专栏  ›  技术社区  ›  Eduardo J. Sanchez

复制构造函数和重载的加法运算符

  •  3
  • Eduardo J. Sanchez  · 技术社区  · 8 年前

    我正在复习C++中的运算符重载。只是为了好玩我正在实施 BigInt 班级。

    我要重载的第一个运算符是 加法运算符 . 我已决定将此运算符重载为友元非成员函数。这里有一段代码:

    #include <cassert>
    #include <iostream>
    #include <string>
    
    class BigInt{
     public:
      friend BigInt operator+(const BigInt &bi1, const BigInt &bi2);
    
      BigInt() {}
      explicit BigInt(const std::string &in) {
        if (in.size() != 0) {
          for (auto cc = in.rbegin(); cc != in.rend(); ++cc) {
            value_.push_back(*cc);
          }
        }
      }
      std::string value() {
        std::string actual_value{};  // Reversed string.
        for (auto cc = value_.rbegin(); cc != value_.rend(); ++cc) {
          actual_value.push_back(*cc);
        }
        return actual_value;
      }
    
     private:
      std::string value_;  // String of digits as characters.
    };
    
    BigInt operator+(const BigInt &bi1, const BigInt &bi2) {
      BigInt result{};
    
      result.value_ = "4421";
      return result;
    }
    
    int main() {
      std::cout << "Test addition operator... ";
      std::string number{"1234"};  // Number 1,234.
      BigInt mm(number);
      std::string number_ten{"10"};  // Number 10.
      BigInt nn(number_ten);
    
      BigInt mm_nn = mm + nn;
    
      std::string expected_result{"1244"};  // 1,234 + 10 = 1,244.
      assert(mm_nn.value() == expected_result);
      std::cout << "ok." << std::endl;
    }
    

    这段代码模拟了加法的行为。它编译并运行。但是当我为 大整数 类,此代码停止工作。即,如果我将此添加到类声明中:

    explicit BigInt(const BigInt &in): value_(in.value_) {}

    代码甚至不编译。已编码的加法函数返回 大整数 . 为此,必须定义一个复制构造函数。如果我自己不定义它,那么编译器就会这样做。编译器生成的是什么,而不是用添加的复制构造函数生成的?下面是我得到的编译错误:

    $ g++ -std=c++14 -g mwe.cpp 
    mwe.cpp: In function ‘BigInt operator+(const BigInt&, const BigInt&)’:
    mwe.cpp:34:10: error: no matching function for call to ‘BigInt::BigInt(BigInt&)’
       return result;
              ^
    mwe.cpp:9:3: note: candidate: BigInt::BigInt()
       BigInt() {}
       ^
    mwe.cpp:9:3: note:   candidate expects 0 arguments, 1 provided
    mwe.cpp: In function ‘int main()’:
    mwe.cpp:44:23: error: no matching function for call to ‘BigInt::BigInt(BigInt)’
       BigInt mm_nn = mm + nn;
                           ^
    mwe.cpp:9:3: note: candidate: BigInt::BigInt()
       BigInt() {}
       ^
    mwe.cpp:9:3: note:   candidate expects 0 arguments, 1 provided
    

    由此看来,编译器需要一个我没有提供的复制构造函数。现在。。。如果我移除 explicit 关键词,一切正常。但是,我看到了使用显式复制构造函数的实现,例如: Explicit copy constructor

    我错过了什么?为什么不能在重载加法运算符时显式复制此副本构造函数?一般来说,复制构造函数应该显式化吗?

    1 回复  |  直到 8 年前
        1
  •  4
  •   R Sahu    8 年前

    创建复制构造函数 explicit 没有道理。除去它。

    BigInt(const BigInt &in): value_(in.value_) {}
    

    概念问题 明确的 复制构造函数

    创建复制构造函数 明确的 使无法从函数返回对象。

    让我们将代码简化为以下内容:

    struct BigInt
    {
       BigInt() {}
       explicit BigInt(const BigInt &in) {}
    };
    
    BigInt operator+(const BigInt &bi1, const BigInt &bi2)
    {
       BigInt result;
       return result;
    }
    
    int main() {}
    

    排队 return result ,编译器依赖于复制构造函数返回对象。如果复制构造函数是显式的,则 BigInt 被构造为返回值。

    尝试使用:

    BigInt operator+(const BigInt &bi1, const BigInt &bi2)
    {
       BigInt result;
       return BigInt(result);
    }
    

    是徒劳的,因为这相当于:

    BigInt operator+(const BigInt &bi1, const BigInt &bi2)
    {
       BigInt result;
       BigInt result1(result);
       return result1;
    }
    

    不管你在函数中做什么,问题仍然存在。

    推荐文章