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

时间:2019-10-05 11:05:25

标签: 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 ***

1 个答案:

答案 0 :(得分:3)

首先:很高兴看到您使用std::shared_ptr!我认为您的问题是对象的复制。由于我不知道它只是拼写错误还是其他内容,因此我将对其进行详细说明。让我们看一下您的一些代码:

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

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

您可以像使用std::shared_ptrstartingRoom一样使用endingRoom来解决此问题。另外,您可以只编写dungeon::Door startingRoomDoor;并拥有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);
}

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

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