-1

在编译时,当它返回添加对象的结果时,它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;
}
4

1 回答 1

0

根据 C++ 17 标准(12.8 复制和移动类对象)

7 如果类定义没有显式声明复制构造函数,则隐式声明一个。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况。

此外,移动构造函数至少被定义为已删除,因为明确定义了复制赋值运算符。

operator +因此,您需要显式定义形成返回对象所需的复制构造函数。

请注意,类定义还有其他缺点。例如,数据成员name可以等于nullptr。这是默认构造函数允许的。在这种情况下,cppy 赋值运算符可以调用由于该语句而导致的未定义行为

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

字符串文字具有常量字符数组的类型。因此,默认构造函数的第一个参数应声明为具有类型const char *

于 2020-07-13T15:30:08.460 回答