как вернуть результат сложения двух объектов класса - PullRequest
0 голосов
/ 13 июля 2020

При компиляции отображается sme error как использование функции удаления constexpr Player::Player(const Player&), когда он возвращает результат добавления объектов.

#include <bits/stdc++.h>

using namespace std;

class Player
{
  char* name;
  int num;

 public:
  Player(char* str = nullptr, int n = -1)
      : name{str}
      , num{n}
  {
    if (str != nullptr)
    {
      name = new char[strlen(str) + 1];
      strcpy(name, str);
      str = nullptr;
    }
  }

  Player& operator=(const Player& temp)
  {
    delete[] this->name;
    this->name = new char[strlen(temp.name) + 1];
    strcpy(this->name, temp.name);
    this->num = temp.num;
  }

  Player operator+(const Player& temp);
};

Player Player::operator+(const Player& temp)

{
  char* str = new char[strlen(name) + strlen(temp.name) + 1];

  strcpy(str, name);
  strcat(str, temp.name);

  int n = num + temp.num;

  Player result{str, n};

  delete[] str;

  return result;
}

int main()

{
  Player p1{"abc", 11};
  Player p2{" xyz", 9};
  Player p3;

  p3 = p1 + p2;
}

1 Ответ

0 голосов
/ 13 июля 2020

Согласно стандарту C ++ 17 (12.8 Копирование и перемещение объектов класса)

7 Если в определении класса явно не объявляется конструктор копирования, он объявляется неявно. Если определение класса объявляет конструктор перемещения или оператор присваивания перемещения, неявно объявленный конструктор копирования определяется как удаленный; в противном случае он определяется как значение по умолчанию (8.4). Последний случай считается устаревшим, если класс имеет объявленный пользователем оператор присваивания копии или объявленный пользователем деструктор.

Также конструктор перемещения определяется как удаленный хотя бы потому, что там явно определен оператор присваивания копии.

Таким образом, вам необходимо явно определить конструктор копирования, который требуется operator + для формирования возвращаемого объекта.

Обратите внимание на это определение класса имеет и другие недостатки. Например, член данных name может быть равен nullptr. Это разрешено конструктором по умолчанию. В этом случае оператор присваивания cppy может вызвать неопределенное поведение из-за этого оператора

this->name = new char[strlen(temp.name) + 1];
                      ^^^^^^^^^^^^^^^^^

И строковые литералы имеют типы постоянных массивов символов. Таким образом, первый параметр конструктора по умолчанию должен быть объявлен как имеющий тип const char *.

...