为返回的shared_ptr分配值不会按预期运行

时间:2015-04-25 23:26:12

标签: c++ c++11 shared-ptr

我有shared_ptr<Room>个对象的私有三维向量,如下所示:

private:
    vector<vector<vector<shared_ptr<Room>>>> world;

在同一个班级中,我提供对Room个对象的访问权限:

public:
    shared_ptr<Room> room_at(const int & x, const int & y, const int & z) const
    {
        return world.at(x).at(y).at(z);
    }

同样在同一个班级中,我初始化world结构:

for (int x = 0; x < C::WORLD_X_DIMENSION; ++x)
{
    vector<vector<shared_ptr<Room>>> row;
    for (int y = 0; y < C::WORLD_Y_DIMENSION; ++y)
    {
        vector<shared_ptr<Room>> vertical_stack; // "stack"
        for (int z = 0; z < C::WORLD_Z_DIMENSION; ++z)
        {
            vertical_stack.push_back(shared_ptr<Room>(nullptr));
        }
        row.push_back(vertical_stack);
    }
    world.push_back(row);
}

稍后,我想将Room对象保存到world

void add_room_to_world(const int & x, const int & y, const int & z)
{
    shared_ptr<Room> room = make_shared<Room>(); // create an empty room

    /* (populate room's member fields) */

    // add room to world
    room_at(x, y, z) = room; // This doesn't work as expected
}

shared_ptr中的world按预期开始为nullptr,但不会在上一行上发生变化。

根据我在SO上发现的内容,我尝试了operator=(上方),.reset(room)make_shared<Room>(room)(使用实际的Room对象而非shared_ptr<Room>}但在所有情况下,shared_ptr内的world仍设置为nullptr

将对象分配到world的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

room_at返回一个值。当从函数返回它时,它将被复制,因此您对返回值执行的任何操作都不会影响原始值。如果要更改原始值,则必须返回如下引用:

shared_ptr<Room>& room_at(const int & x, const int & y, const int & z) const
{
   return world.at(x).at(y).at(z);
}

如果您不希望您的班级用户能够这样做,请将此方法声明为私有并保持原始状态。

答案 1 :(得分:3)

room_at返回一个值。当你改变这个值时,谁在乎呢?你只是变异一些随机的临时。它对从中复制的对象没有意义。

为了支持你想要的东西,room_at需要返回一个可变引用 - 对于这种方式的公共API来说是一个非常糟糕的主意。

您希望提供一个返回可变引用的类似私有方法,然后实现room_at,只返回该函数引用的对象的副本。