编译器错误 C2280,试图引用已删除的函数 operator=
Posted
技术标签:
【中文标题】编译器错误 C2280,试图引用已删除的函数 operator=【英文标题】:Compiler error C2280, attempting to reference a deleted function operator= 【发布时间】:2017-12-10 02:35:21 【问题描述】:我正在编写一个大富翁游戏。而且我真的很喜欢排序功能,它可以生成漂亮干净的输出,在这种情况下,可以按组对玩家拥有的属性进行排序。
首先这是我的属性排序功能
bool propertySort(Property a, Property b) return a.getGroup() < b.getGroup();
现在,玩家拥有这些属性的列表。
#pragma once
#include <string>
#include <vector>
#include "Dice.h"
#include "Property.h"
class Player
public:
...
private:
int curMoney 1500 ;
int curLocation 0 ;
int playerNum 0 ;
std::string name;
std::vector<Property> ownedProperties;
int curDiceRoll;
;
如您所见,它是底部的私有属性,已初始化为 0 个属性。
因此,在我的 main 属性分类器中,我会将属性显示在板上供玩家查看,分类器功能不断给我错误 C2280。我知道正是这个排序函数引发了这个错误,因为如果我注释掉排序行,程序运行良好。我敢肯定,由于我是初学者,因此我不知道这是显而易见的事情。如果有人能提供关于它是什么的见解,那就太好了,谢谢!
void viewProperties(Player& p)
string prompt = "Select a player to view their properties";
vector<string> playerNames;
for (Player p : players)
playerNames.push_back(p.getName());
Menu propertiesMenuSelection prompt, playerNames ;
vector<Property> propertiesOfSelectedPlayer = players[propertiesMenuSelection.getChoice()].getOwnedProperties();
sort(propertiesOfSelectedPlayer.begin(), propertiesOfSelectedPlayer.end(), propertySort);
system("CLS");
如果这有帮助,这里是 Property 类
#pragma once
#include "Space.h"
#include <array>
#include <vector>
extern std::vector<Player> players;
class Property : public Space
public:
Property(std::string name, std::vector<int> values);
~Property();
void run(Player&) override;
std::vector<std::string> boardOut() const override;
std::string getName() const override;
...
private:
std::string name;
int group;
int price;
int buildingCost;
int buildings;
Player* ownerPtr = nullptr;
std::array <int, 6> rent;
const std::array <std::string, 10> groups "Brown", "Light Blue", "Pink", "Orange", "Red", "Yellow", "Green", "Dark Blue", "Railroad", "Utility" ;
;
这里是要求非常简单的空间类。
#pragma once
#include <string>
#include <vector>
class Player;
class Space
public:
virtual void run(Player&) = 0;
virtual std::string getName() const = 0;
virtual std::vector<std::string> boardOut() const = 0;
;
【问题讨论】:
const std::array
-- 这个成员变量可能是副本不可用的原因。
因为您不能分配给const
变量。愚蠢的例子:ideone.com/AieNNX
这里有一个更好的错误消息:ideone.com/6RiXzJ
现在我想起来了,这种情况很少见,您需要赋值运算符而不需要需要the rest of the big three。凉爽的。我现在有一个例子!
@Alex -- 用外行的话来说,编译器无法弄清楚你想对该成员做什么,因为它是const
。 Here is an old, but related article from Dr. Dobbs
【参考方案1】:
删除的函数是赋值运算符。无法分配Property
,因为无法分配const
成员groups
。对此最合乎逻辑的解决方案是将groups
声明为static
,以便Property
的所有实例共享它并且不需要分配它。例如:
static const std::array <std::string, 10> groups;
groups
的存储空间需要在类定义之外进行分配和初始化:
const std::array <std::string, 10> Property::groups "Brown", "Light Blue", "Pink",
"Orange", "Red", "Yellow", "Green",
"Dark Blue", "Railroad", "Utility" ;
TL;DR
赋值运算符的默认行为是将源的所有成员复制到目标中,而不对副本应用任何智能。这意味着一个非常简单的例子
class test
public:
const int a = 10;
;
会生成等价的
test& operator=(const test & src)
a = src.a;
return *this;
这是不可能的,因为a
是const
,即使没有更改也无法更改。
您可以添加自己的赋值运算符
test& operator=(const test & src)
// deliberately does not assign a = src.a
return *this;
但您想要这样做的唯一原因是如果没有方法可以在初始化时更改a
的值。如果您无法更改a
,则test
的所有实例都具有相同的a
值,并且a
也可能是static
成员。
两个test
s 的a
值不同的失败示例:
int main()
test a11; // a const variable cannot be changed after initialization,
// but this initializes a to 11.
test b; // uses the default of 10
std::cout << a.a << ',' << b.a; // output 11,10
a = b; //this can't really be be done. a can never equal b
【讨论】:
完美!多么棒的解释。那个静态解决方案正是我需要和实现的,非常感谢! @Alex 没问题。帮助您为时已晚,但希望下一个遇到此问题的人能找到它。 我的想法完全正确,如果其他人遇到此错误,如果您使用类似 sort 的东西并且它不知从何而来,这可能会非常令人困惑。希望他们能找到这个问题,看看你的答案。也许他们会意识到无限制地使用非静态 const 是多么危险。这对我和其他人来说都是很棒的一课!以上是关于编译器错误 C2280,试图引用已删除的函数 operator=的主要内容,如果未能解决你的问题,请参考以下文章
VS2019 C++ 错误 C2280 试图引用已删除的函数 inl
C++错误C2280 - 试图引用一个已删除的函数 - 在基元类型上。