Копировать конструктор и перегруженный оператор сложения

Я рассматриваю перегрузку операторов в C ++. Просто для удовольствия я реализую BigInt учебный класс.

Первый оператор, который я хочу перегрузить, это оператор сложения. Я решил перегрузить этот оператор как функцию, не являющуюся другом. Вот MWE этого кода:

#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, Для этого должен быть определен конструктор копирования. Если я не определю это сам, то компилятор сделает это. Что производит компилятор, который я не создаю с добавленным конструктором копирования? Вот ошибка компиляции, которую я получаю:

$ 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 Ключевое слово, все работает. Тем не менее, я видел реализации с явным конструктором копирования, например: Явный конструктор копирования

Что мне не хватает? Почему я не могу сделать этот конструктор копирования явным при перегрузке оператора сложения? Должны ли вообще конструкторы копирования быть явными?

3

Решение

Создание конструктора копирования explicit не имеет смысла. Убери это.

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

Концептуальная проблема с explicit Копировать конструктор

Создание копии конструктора explicit делает возврат объекта из функции невозможным.

Давайте упростим ваш код до следующего:

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;
}

Проблема продолжает существовать независимо от того, что вы делаете в функции.

4

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector