【问题标题】:deleted function, can't rewrite one record to another, objects删除的功能,不能将一条记录重写为另一条记录,对象
【发布时间】:2020-12-04 12:34:24
【问题描述】:

我是新来的,如果我做错了很抱歉。

我做了一个学校项目。在功能上我不能简单地使用

tab[i] = tab[i + 1];

它显示错误: 无法引用函数“Pilkarz::operator=(const Pilkarz&)”(隐式声明)的元素 - 这是已删除的函数

这是我的第一堂课:

class Player
{
protected:
string Name;
string SName;
string Position;
int Age;
float AvGoals;
int los;
fstream plik;
string poz[7] = { "Napastnik", "Skrzydlowy", "Obronca", "Napastnik", "Pomocnik", "Bramkarz", "Boczny Obronca" };
};

public:
Player(string="Imie", string="Nazwisko", string="Pozycja", int=0, float=0, float=1);
};

这是我的第二节课:

class Club:public Player
{
protected:
Player* tab;
int counter, current, size;
fstream plik2;

private:
int i;
int skrzydlowy = 0, pomocnik = 0, bObronca = 0, bramkarz = 0;

public:
Club(int);
};

我想做的功能:

void Club::deleteCurrent() {
        for (i = current; i < size - 1; i++)
        {
            tab[i] = tab[i + 1];
        }
}

问题是我不能使用这个:tab[i] = tab[i +1]; 我必须使用 setter 和 getter 才能使其工作。有什么问题? 我使用 Visual Studio Enterprise 2019。

【问题讨论】:

  • fstream plik; -- 无法复制此成员。无法复制流
  • @molbdnilo 你的意思是每个 Player 对象都有自己的文件很糟糕? Class Player 不应该有 fstream 成员?
  • @l1ght 不一定是坏,但这取决于它的用途。即使你有一个“每个对象一个文件”的结构,文件 I/O 通常(并且更方便)是在对象之外处理的。

标签: c++ class object


【解决方案1】:

成员fstream plik; 不可复制。它有一个已删除的复制构造函数:https://en.cppreference.com/w/cpp/io/basic_fstream/basic_fstream

因此编译器无法生成默认的复制赋值运算符。您可以从班级中删除 fstream plik; 或添加用户定义的复制赋值运算符:

Pilkarz &operator=(const Pilkarz &p) {
    /* copy all members */
    return *this;
}

【讨论】:

  • 还有其他解决方案吗?我需要 fstream 才能使我的其他功能正常工作。当我做tab[i] = tab[i+1]; 时,它会复制Class 中的所有元素吗?偶函数?
  • @l1ght 不,您不能复制 fstream 类型的对象。您必须为此成员指定副本的行为。但可能这首先不应该是这个类的成员。不复制成员函数。它们属于类而不属于对象。
  • 好的做法是将输入/输出流 (fstream) 之类的东西作为参数传递给函数。例如,您想将Player 打印到某个文件中,您宁愿添加Player::Print(ostream&amp; plik); 而不是在Player 对象中存储一些fstream 并拥有Player::Print()
  • 谢谢,@ThomasSablik 现在我明白了。 @seb 为什么是 Print(ostream&amp; plik); 而不仅仅是 Print(fstream plik); ?
  • @l1ght -- 如果我想打印到任何类型的流,而不仅仅是文件流怎么办?例如:std::ostringstream strm; Print(strm); 如果类型为ostream&amp;,则将输出发送到字符串流。
【解决方案2】:

隐式声明的赋值运算符被删除,因为class Pilkarz 的成员之一删除了赋值运算符

示例代码: https://godbolt.org/z/eGosWc

可以看到fstream flk;成员已经删除了它的隐式复制赋值操作符。

<source>:15:9: note: copy assignment operator of 'Pilkarz' is implicitly deleted because field 'plik' has a deleted copy assignment operator
fstream plik;

您需要使用仅复制允许复制的成员的显式实现来覆盖 class Pilkarz 复制赋值运算符的默认实现。

【讨论】:

  • 好的,我现在明白了。但是如何定义可以复制的参数呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 2019-02-18
相关资源
最近更新 更多