调试记录(展示)

  1. m尝试将一个新的Room指针next直接赋值给currentRoom。这会再次产生错误,因为不能将一个指针直接赋值给另一个指针。我们仍然需要获取指针所指向的对象地址:
    currentRoom = &*next; 
  2.  编译多文件程序时,其中一个文件必须包含main函数,链接器使用它作为程序的入口点。
    g++ -o -std=c++20 main.cpp main.cpp player.cpp room.cpp
  3. 通过使用this指针,我们可以明确地指定我们要访问的成员变量,(roomNumber和description是Room类里的成员变量)而不是形参。这避免了混淆,确保代码按预期工作。
void Room::init(int roomNumber, string description, map<string, Room*> exits) { 
    roomNumber = roomNumber;  
    description = description;
}//这是错误的,会将形参赋给自身
void Room::init(int roomNumber, string description, map<string, Room*> exits) { 
    this->roomNumber = roomNumber;  
    this->description = description;
}//这是正确的。

                没有命名冲突风险的时候可以忽略,但是我觉得this指针让代码更易读。

  1. 在最初编写map时,存储的键值均为string,发现无法将direction和Room链接起来,所以将值的类型改为了Room。
  2. 考虑到动态更新player所在的Room,改用了指针,指针可以改变指向的对象,而且仅储存地址而不是整个对象。
  3. 想将新定义的map传入到不同Room里,在Room类中使用this指针来访问exits成员变量并将其更新为传入方法的exits映射
    void Room::setExits(map<string, Room*> exits) {
        this->exits = exits;
    }
  4. 由于findExits()方法是Room类的一个成员,当调用room->findExits()时,this已经指向要访问的特定Room实例。所以,不需要向该方法传递要访问的Room,它已经通过this隐式传递。
  5. 循环的时候,getExit()的调用少了一轮,需要在调试后不断修改 。
  6. 使用构造函数不太清晰,在Room类里没有定义默认构造函数,在player初始化所在房间的时候调用room出现问题。更改后没有使用构造函数,而是使用了普通的成员函数。
  7. 添加默认构造函数:
    class Room {  
    public: 
        // 默认构造函数
        Room() {}
        ...
    }
  8. 运行时,第一个房间的出口都打印正常,在输入一个direction后,下一个房间的description可以正常打印,但是该room类的名为exits的map里没有任何direction,也就是下一个房间里有description却没有任何出口了。更正后将map也作为了Room类里初始化房间函数的一个参数。
  9. 对8再次更正:将 Room 实例作为值插入 exits 映射时, exits 实际上保存的不是 Room 对象本身,而是 Room 对象的副本。所以从 exits 获取该值时,获得的不是原 Room 对象,而是其副本。而无法在副本上调用方法,只能调用原 Room 对象的方法。所以当 map 中的值代表类时,应使用 Room* 指针作为 exits 映射的值,而不是 Room 实例。从 exits 获取值时,获得的是 Room 对象的实际地址(通过原指针),而不是副本。所以可以使用指针调用 Room 对象上的方法。问题解决。举个栗子:
    Room room1;
    
    map<string, Room> exits;  // 使用 Room 实例作为值,这是错误的
    exits["north"] = room1;     // exits 现在保存 room1 的副本
    
    // 现在无法调用 room1 方法 - exits["north"] 是一个副本
    exits["north"].fun();   // 错误,无法调用对象方法
    Room room1; 
    
    map<string, Room*> exits;   // 使用 Room* 指针作为值
    exits["north"] = &room1;    // 存储 room1 的地址
    
    Room* north = exits["north"]; // 获取 room1 的地址 
    north->fun();      // 可以调用对象方法
  10. 默认构造函数应该放在类定义内,与其他构造函数一起。例如:
    class Player {
      public:
        Player() {}   // 默认构造函数
        
        Player(string name) { ... }  // 其他构造函数
        
        // ...
    };
    默认构造函数没有参数,并用于在未指定构造函数参数的情况下初始化类。它将类的所有成员变量初始化为默认值。如果类没有定义任何构造函数,编译器会自动生成一个默认构造函数。但是,一旦定义了任何构造函数,编译器就不再生成默认构造函数。所以如果需要一个默认构造函数,必须显式定义它。默认构造函数应放在公共(public)类定义内,与其他构造函数一起。没有特定的顺序规则,可以按任何需要的顺序定义构造函数。 
  11. 构造函数和成员函数的主要区别是:

        构造函数:- 名称与类名相同

                        - 无返回类型

                         - 被自动调用以初始化对象                                                                                        

        成员函数:- 可以有任意名称

                        - 有返回类型(可以是void)

                        - 必须被调用才会执行

// 构造函数
Room(int roomNumber, string description) {
    this->roomNumber = roomNumber;
    this->description = description; 
}

// 成员函数
void init(int roomNumber, string description) {
    this->roomNumber = roomNumber;
    this->description = description;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值