我使用现代C++
创建一个非常简单的游戏引擎,采用旧的基于文本的冒险风格。
我有这样的Room类:
class Room
{
public:
Room(void);
void connect(shared_ptr<Room> room, Direction direction);
private:
std::shared_ptr<Room> north;
std::shared_ptr<Room> south;
std::shared_ptr<Room> east;
std::shared_ptr<Room> west;
};
connect()
基本上是north
,south
等指针的设定者。
它看起来像这样:
void Room::connect(std::shared_ptr<Room> room, Direction direction)
{
switch (direction)
{
case Direction::NORTH:
this->north = room;
break;
case Direction::SOUTH:
this->south = room;
break;
case Direction::EAST:
this->east = room;
break;
case Direction::WEST:
this->west = room;
break;
default:
std::cerr << "[ERROR] Invalid direction" << std::endl;
}
}
现在我可以致电
Room example_room{};
Room another_room{};
example_room.connect(std::make_shared<Room>(another_room), Direction::NORTH)
another_room.connect(std::make_shared<Room>(example_room), Direction::SOUTH)
当我启动lldb
并查看变量时,example_room::north
将是指向std::shared_ptr<Room>
对象的Room
,但是,此对象并非如此似乎是another_room
,因为其south
数据成员是std::shared_ptr
,其中包含nullptr
。
所以他们指向其他房间,但他们并没有指向对方。我知道原因必须在connect()
成员函数的某处,但我不知道在哪里。
答案 0 :(得分:3)
make_shared
从调用它的参数创建一个新对象,并返回指向新对象的shared_ptr
。在示例代码中,它使两个原始房间的副本。这不是我们需要的东西。事实上,共享指针在这个应用程序中是错误的。将有几个属于应用程序的房间,它们应该在全局或某种管理其生命周期的容器中定义。每个房间都应该有一个指向邻居的普通指针。没有任何空间来管理其邻居的生命。这是应用程序的责任。
答案 1 :(得分:0)
您正在堆栈上创建example_room
和another_room
个实例,但是要connect()
您使用make_shared()
传递在堆上创建的全新实例。让example_room
和another_room
为shared_ptr
可以,但是!正如@PiotrSkotnicki在评论中提到的那样,您不应该使用shared_ptr
进行通告依赖性。使用weak_ptr
代替Room
成员。
e.g:
class Room
{
public:
// ...
void connect(weak_ptr<Room> room, Direction direction);
private:
std::weak_ptr<Room> north;
std::weak_ptr<Room> south;
// ...
}
然后:
auto example_room = std::make_shared<Room>();
auto another_room = std::make_shared<Room>();
example_room->connect(another_room, Direction::NORTH)
another_room->connect(example_room, Direction::SOUTH)
只要您需要这些链接,请确保原始shared_ptr
保持活着状态。