编译器错误C2280,试图引用已删除的函数operator =

时间:2017-12-10 02:35:22

标签: c++ sorting compiler-errors

我正在编写大富翁游戏。而且我真的很喜欢用于制作漂亮干净输出的排序功能,在这种情况下,按照组对玩家拥有的属性进行排序。

首先,这是我的属性分类器功能

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属性。

所以在我的主要物业分拣机中,我会在棋盘上显示属性让玩家看到,分拣机功能不断给我一个错误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");

如果这有助于这里属性类

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

enter image description here

1 个答案:

答案 0 :(得分:5)

已删除的功能是赋值运算符。无法分配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;
}

这是不可能的,因为aconst,即使没有变化也无法更改。

您可以添加自己的作业运算符

test& operator=(const test & src)
{
    // deliberately does not assign a = src.a
    return *this;
}

但是你想要这个的唯一原因是,如果没有方法可以在初始化时更改a的值。如果您无法更改a,则test的所有实例都具有a的相同值,而a也可能是static成员。

两个test具有a的不同值的失败示例:

int main()
{
    test a{11}; // 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
}