c++ - 我创建的类似乎错误地设置了它的局部变量

标签 c++ oop

抱歉,我在这件事上缺乏经验,如果这是一个简单的答案,但我正在为一项作业编写一个 C++ 程序,并且我一生都找不到解决方案。

我创建了一个名为 Door 的类,它拥有一个本地变量,用于存储它所连接的房间。此外,每扇门都通过另一个局部变量相互连接。记录每扇门所连接的门的局部变量是一个指针(赋值的要求)。

门类通过取消引用指针(通过 * 运算符)将其连接到的门传回。

另一个类 Room,在四个方向(北、东等)后面的变量名称中存储四个门,并由一个简单的整数标识,该整数可以通过函数传递以接收指向房间对象的共享指针。

我遇到的问题是在我的类中,该类负责创建房间并用门填充它们,然后将门彼此连接,程序能够设置 Door 类的局部变量,但是,一旦刚刚设置了变量的门对象被引用回它似乎设置了错误的变量。

在下面的示例中,正在创建的房间的整数是 1 和 2。

这不是完整的代码,只是相关信息的片段

class Door{

    private:
        Door *_connectedDoor;
        int _connectedRoom;
        bool _isEntrance;
        bool _isExit;
};

void Door::connectDoor(Door connectedDoor){

    if( _isExit == true || _isEntrance == true)
    {
        std::cout << "Cannot connect, is an entrance / exit";
    }

    else
    {   
        _connectedDoor = &connectedDoor;
    }
};

Door Door::getConnectedDoor(){

    return *_connectedDoor;
}

int Door::getRoom(){
   std::cout << std::endl << "*** passing connected room:" << _connectedRoom << " ***" << std::endl;
   return _connectedRoom;
};

void Door::setRoom(int room){

    std::cout << std::endl << "*** setting connected room:" << room << " ***" << std::endl;
    _connectedRoom = room;

};





class Room{
  private:
     int _id;
     std::string _description;
     Door _northDoor;
};

void Room::setNorth(Door north){
_isDoorNorth = true;
    _northDoor = north;
    std::cout << std::endl << "*** configuring doors room internally to:" << _id << " ***" << std::endl;
    north.setRoom(_id);
};

类游戏

void Game::connectRooms(int room1, int room2, std::string startingDirection)
{
    std::cout << std::endl << "*** connecting rooms ***" << std::endl;

    std::shared_ptr<dungeon::Room> startingRoom = _currentDungeon.retrieveRoom(room1);
    std::shared_ptr<dungeon::Room> endingRoom = _currentDungeon.retrieveRoom(room2);
    dungeon::Door startingRoomDoor = *new dungeon::Door();
    dungeon::Door endingRoomDoor = *new dungeon::Door();

    std::cout << std::endl << "*** configuring room:" << startingRoom->id() << " ***" << std::endl;
    std::cout << std::endl << "*** configuring room:" << endingRoom->id() << " ***" << std::endl;

    startingRoom->setNorth(startingRoomDoor);
    endingRoom->setSouth(endingRoomDoor);

    std::cout << std::endl << "*** configuring doors room:" << startingRoomDoor.getRoom() << " ***" << std::endl;
    std::cout << std::endl << "*** configuring doors room:" << endingRoomDoor.getRoom()  << " ***" << std::endl;

    startingRoomDoor.connectDoor(endingRoomDoor);
    endingRoomDoor.connectDoor(startingRoomDoor);
};

输出:

*** connecting rooms ***

*** configuring room:1 ***

*** configuring room:2 ***

*** configuring doors room internally to:1 ***

*** setting connected room:1 ***

*** configuring doors room internally to:2 ***

*** setting connected room:2 ***

*** configuring doors room:
*** passing connected room:1835344 ***
1835344 ***

*** configuring doors room:
*** passing connected room:1835344 ***
1835344 ***

预期:

*** configuring doors room:
*** passing connected room:1 ***
1 ***

*** configuring doors room:
*** passing connected room:2 ***
2 ***

最佳答案

首先:很高兴看到您使用 std::shared_ptr!我认为你的问题是对象的复制。由于我不知道这是否只是一个拼写错误或其他原因,我会更详细地解释一下。让我们看一下您的一些代码:

dungeon::Door runningRoomDoor = *new dungeon::Door(); 这将执行以下操作:

  1. 使用 new 运算符创建 dungeon::Door 的新实例。这将返回一个指向新实例的指针。
  2. 使用 * 取消引用该指针。
  3. 使用新实例初始化 startingRoomDoor,从而调用复制构造函数并复制新实例。
  4. 指向新实例的指针超出范围,导致内存泄漏。

您可以使用 std::shared_ptr 修复此问题,就像使用 startingRoomendingRoom 一样。或者,您可以只编写 dungeon::Door runningRoomDoor; 并拥有 dungeon::Door 的初始化实例。在这种情况下,构造函数会被自动调用。

接下来是您的房间功能:

void Room::setNorth(Door north){
_isDoorNorth = true;
    _northDoor = north;
    std::cout << std::endl << "*** configuring doors room internally to:" << _id << " ***" << std::endl;
    north.setRoom(_id);
}

在这里,您可以按值传递。这意味着,您传递给此函数的值实际上会被复制,并且在函数内您仅修改 Room 的拷贝。在函数结束时,north 被销毁,因为它的作用域到此结束。如果您像这样通过引用传递,则可以解决此问题: void Room::setNorth(Door &north) 现在,您实际上修改了传递给函数的值而不是拷贝。

但请注意! _northDoor = Northern; 行仍将复制 north。即使 north 是通过引用传递的。也许您只想存储一个指针而不是整个实例?您还可以使用 std::shared_ptr 来实现此目的。

关于c++ - 我创建的类似乎错误地设置了它的局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58247725/

相关文章:

java - 正确实现所有相等对象的属性

c# - C# 和 VB 中的 Overridable 和 Override

python - 如何在对象上应用连续的方法

c++ - 将 Doxygen 注释与 cppcheck-suppress 混合

c# - 旧 C++ 应用程序和新 C# 应用程序之间的桥梁

c++ - 一旦失去焦点如何更新屏幕

PHP OOP 与 MySQL

javascript - 使用 this 和 prototype 在 JavaScript 中定义类的方法有什么区别?

c++ - 有人可以向我解释这行代码吗?

c++ - 进程退出和对线程的影响