繁体   English   中英

如何在没有指针的情况下正确地将 class 对象插入 map?

[英]How to insert class objects to map correctly without pointers?

这是我的代码:

登录用户.h

#pragma once
#include <string>

using std::string;

class LoggedUser {
private:
    string m_username;
public:
    LoggedUser(string username);
    string getUsername() const;
    bool operator==(LoggedUser loggedUser) const;
};

房间.h

#pragma once
#include <LoggedUser.h>
#include <string>
#include <vector>

using std::vector;
using std::string;

typedef struct RoomData {
    unsigned int id = 0;
    string name;
    unsigned int maxPlayers = 4;
    const unsigned int timePerPlay = 10;
    bool isActive = false;

    RoomData& operator=(const RoomData& roomData) {
        this->id = roomData.id;
        this->isActive = roomData.isActive;
        this->maxPlayers = roomData.maxPlayers;
        this->name = roomData.name;
        return *this;
    }
} RoomData;

class Room {
private:
    RoomData m_metadata;
    vector<LoggedUser> m_users;
public:
    Room(const Room& room);
    Room(RoomData roomData, LoggedUser loggedUser);
    int getUserIndex(const LoggedUser& loggedUser);
    void addUser(LoggedUser loggedUser);
    void removeUser(LoggedUser loggedUser);
    vector<LoggedUser> getAllUsers();

    unsigned int getId();
    string getName();
    unsigned int getMaxPlayers();
    bool getIsActive();
};

房间管理器.h

#pragma once
#include <map>
#include "Room.h"

class RoomManager {
private:
    std::map<unsigned int, Room> m_rooms;
public:
    void createRoom(LoggedUser loggedUser, RoomData roomData);
}

房间管理器.cpp

#include "RoomManager.h"

void RoomManager::createRoom(LoggedUser loggedUser, RoomData roomData)
{
    m_rooms[roomData.id] = Room(roomData, loggedUser);
}

问题出在 function createRoom 中的文件 RoomManager.cpp 中,我正在尝试将他的 ID 插入到地图<unsigned int, Room> 中,但我收到此错误“C2512 'Room::Room': no适当的默认构造函数可用"

现在,我知道我可以通过插入 Room 的指针而不是 object 本身来解决这个问题,但我想知道是否有办法在没有指针的情况下做到这一点,这样我就知道我的代码中出了什么问题。 感谢所有帮助的人。

m_rooms[roomData.id] = Room(roomData, loggedUser); 声明您使用std::map::operator[] ,其中...

...返回对映射到等效于(请求的)键的键的值的引用,如果这样的键不存在,则执行插入

因此,只有在mapped_type具有默认构造函数时,我们才可以使用运算符。 由于要在map中插入一个“后备”值(如果我们访问一个尚不存在的键),因此需要在运行中默认构造一个。

但是由于您确实为Room提供了非默认构造函数,因此编译器不会为您合成默认构造函数。 因此, Room不是 DefaultInsertable。

所以我们可以通过简单地引入一个 默认的默认构造函数来处理这个问题:

class Room {
    // Other private members as before
public:
    // Other public members as before
    Room() = default;
};

经验教训: std::map::operator[]要求mapped_typeDefaultInsertable 有关更多信息,请参阅 文档

您正在使用operator[]将项目插入std::map 此操作要求插入的项目是DefaultConstructible 1

正如@rawrex 在另一个答案中所解释的那样, Room class 不是DefaultConstructibel

如果您不能或不想添加默认构造函数,也可以使用insert() function 来插入项目。 此 function 没有上述要求。

m_rooms.insert(std::make_pair(roomData.id, Room(roomData, loggedUser)));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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