简体   繁体   中英

Compiler error C2280, attempting to reference a deleted function operator=

I'm programming a Monopoly game. And I really love the sort function for making nice clean outputs, in this instance sorting the properties a player owns by group.

First of all here's my property sorter function

bool propertySort(Property a, Property b) { return a.getGroup() <  b.getGroup(); }

Now, player owns a list of these properties.

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

As you can see it's a private attribute towards the bottom that's initalized to 0 properties.

So in my property sorter in main, where I would display the properties onto the board for the player to see, the sorter function constantly keeps giving me error C2280. I know it's precisely this sort function throwing this error, because if I comment out the sort line the program runs fine. I'm sure it's something obvious I'm ignorant of since I'm a beginner programmer. If anyone could offer insight as to what it is that would be great, thanks!

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");

In case this helps here's the Property class

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

Here is the space class as requested very simple.

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

在此处输入图片说明

The deleted function is the assignment operator. Property cannot be assigned because the const member groups cannot be assigned. The most logical solution to this is to declare groups to be static so that all instances of Property share it and it does not need to be assigned. Eg:

static const std::array <std::string, 10> groups;

and storage for groups needs to be assigned and initialized outside of the class definition:

const std::array <std::string, 10> Property::groups{ "Brown", "Light Blue", "Pink", 
                                                     "Orange", "Red", "Yellow", "Green", 
                                                     "Dark Blue", "Railroad", "Utility" };

TL;DR

The default behaviour of the assignment operator is to copy all of the members of the source into he destination without applying any smarts to the copy. This means a really simple example

class test
{
public:
    const int a = 10;
};

Will generate the equivalent of

test& operator=(const test & src)
{
    a = src.a;
    return *this;
}

which is not possible because a is const and cannot be changed even if there is no change.

You could add your own assignment operator

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

but the only reason you would want this is if there is no method by which you can change the value of a at initialization. If you cannot change a , then all instances of test have the same value of a , and a might as well be a static member.

Example of failure where two test s have a different value for 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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM