首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >复制构造函数和重载加法运算符

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

Stack Overflow用户
提问于 2018-06-11 02:21:27
回答 1查看 139关注 0票数 3

我正在检查C++中的运算符重载。只是为了好玩,我实现了一个BigInt类。

我想为它重载的第一个运算符是加法运算符。我决定将这个运算符作为一个非成员函数重载。下面是这段代码的MWE:

代码语言:javascript
复制
#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;
}

这段代码模拟了加法的行为。它会编译并运行。然而,当我为BigInt类添加一个复制构造函数时,这些代码停止工作。也就是说,如果我将这个添加到类声明中:

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

代码甚至不能编译。代码中的加法函数返回一个构造的BigInt实例的副本。为此,必须定义一个复制构造函数。如果我不自己定义它,那么编译器就会定义它。编译器生成了什么,而我没有用添加的复制构造函数生成呢?下面是我得到的编译错误:

代码语言:javascript
复制
$ 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

我遗漏了什么?为什么我不能在重载加法运算符时显式地使用这个复制构造函数呢?一般来说,复制构造函数应该显式吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-11 03:07:27

将复制构造函数设为explicit没有任何意义。去掉它。

代码语言:javascript
复制
BigInt(const BigInt &in): value_(in.value_) {}

explicit复制构造函数的概念问题

复制构造函数explicit使得从函数返回对象变得不可能。

让我们将您的代码简化为以下代码:

代码语言:javascript
复制
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构造为返回值。

尝试使用:

代码语言:javascript
复制
BigInt operator+(const BigInt &bi1, const BigInt &bi2)
{
   BigInt result;
   return BigInt(result);
}

是徒劳的,因为这等同于:

代码语言:javascript
复制
BigInt operator+(const BigInt &bi1, const BigInt &bi2)
{
   BigInt result;
   BigInt result1(result);
   return result1;
}

无论您在函数中做什么,问题都会一直存在。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50786776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档