unique_ptr 的多维向量中对象的访问方法
Accessing methods of objects held in multidimensional vectors of unique_ptr's
我有一个对象的二维结构初始化如下:
std::vector<std::shared_ptr<tile> > appearance;
for (int x = 0; x < building_data.x_width; x++)
{
appearance.push_back
(std::shared_ptr<tile>(new tile[building_data.y_length]));
}
现在,据我所知,访问 tile 成员函数的唯一方法是使用
appearance.at(x).get()[y].member_function()
这很混乱很麻烦,我觉得我错过了什么。
之前,我对相同的结构使用了 tile**
,语法
tile[x][y]
很好,但原始指针令人头疼。
那么,是否有更好的方法访问数组中保存的对象的函数,其中数组中的第一个元素由向量中保存的智能指针指向?罗嗦但这是我最好的。
首先,shared_ptr
不适用于数组。当没有更多引用时,它调用 delete
而不是 delete[]
如果托管对象是数组,这将导致未定义的行为。你可以阅读它 here.
至于访问 shared_ptr
对象,您可以使用 operator* 取消引用它。
此外,如果您知道向量的最终大小,您可能需要 reserve 一些 space 以避免重新分配。
您可以使用 -> 运算符访问 shared_ptr 管理的对象的成员。这与您使用原始指针的语法相同。
但是,如 Dantez 的回答中所述,您将 运行 遇到删除问题。
此外,您似乎正在构建某种棋盘,也许是为了游戏?您是否考虑过用一维向量和一些访问函数替换多维数组?
// board_width and height should be integers
std::vector<Tile> board;
board.reserve(board_width * board_height);
for (unsigned y_axis = 0; y_axis < board_height; ++y_axis)
{
for (unsigned x_axis = 0; x_axis < board_width; ++x_axis)
{
board.push_back(Tile());
}
}
...
vec2 index_to_coords(unsigned index)
{
return vec2(index % board_width, index / board_width);
}
...
unsigned coords_to_index(const vec2& coords)
{
return (static_cast<unsigned>(coords.y) * board_width) + static_cast<unsigned>(coords.x);
}
我同意 Fibbles 的观点,但我想提供一个替代想法。 Fibble 的方法实际上甚至在 C 语言中也很常见,因为多维结构(矩阵)那样更容易。
但是,如果你坚持二维概念,你可以嵌套向量。考虑:
typedef std::vector< tile > TileRow;
typedef std::vector< TileRow > Tiles;
起初,这可能有点令人困惑,所以要明确创建:
std::vector< std::vector< tile > > t;
然而,对于 typedef,那就是
Tiles t;
现在,那是空的。要使用它,您需要推入一些行,并为每一行推入一些列。你可能不喜欢那样,所以......你可以使用分配功能来设置一些行。例如,如果您需要一个 10 行乘 10 列的矩阵,您可能
t.assign( 10, TileRow( 10, tile() ) );
这里假设 tile 有一个默认构造函数,推送 10 行 TileRow,每行有 10 列默认构造的 tiles。
现在,t[ 1 ]
returns 对第 1 行的引用。因此,t[ 1 ][ 1 ]
是对位置 1,1 处的图块的引用,很像数组。
但是,现在您没有 allocation/deallocation 问题。
类似的事情可以用 std::array 完成,甚至更好。
typedef std::array< tile, 10 > TileRow;
typedef std::array< TileRow, 10 > Tiles;
Tiles t;
此时,t 已准备好使用默认的初始化图块。
我有一个对象的二维结构初始化如下:
std::vector<std::shared_ptr<tile> > appearance;
for (int x = 0; x < building_data.x_width; x++)
{
appearance.push_back
(std::shared_ptr<tile>(new tile[building_data.y_length]));
}
现在,据我所知,访问 tile 成员函数的唯一方法是使用
appearance.at(x).get()[y].member_function()
这很混乱很麻烦,我觉得我错过了什么。
之前,我对相同的结构使用了 tile**
,语法
tile[x][y]
很好,但原始指针令人头疼。
那么,是否有更好的方法访问数组中保存的对象的函数,其中数组中的第一个元素由向量中保存的智能指针指向?罗嗦但这是我最好的。
首先,shared_ptr
不适用于数组。当没有更多引用时,它调用 delete
而不是 delete[]
如果托管对象是数组,这将导致未定义的行为。你可以阅读它 here.
至于访问 shared_ptr
对象,您可以使用 operator* 取消引用它。
此外,如果您知道向量的最终大小,您可能需要 reserve 一些 space 以避免重新分配。
您可以使用 -> 运算符访问 shared_ptr 管理的对象的成员。这与您使用原始指针的语法相同。
但是,如 Dantez 的回答中所述,您将 运行 遇到删除问题。
此外,您似乎正在构建某种棋盘,也许是为了游戏?您是否考虑过用一维向量和一些访问函数替换多维数组?
// board_width and height should be integers
std::vector<Tile> board;
board.reserve(board_width * board_height);
for (unsigned y_axis = 0; y_axis < board_height; ++y_axis)
{
for (unsigned x_axis = 0; x_axis < board_width; ++x_axis)
{
board.push_back(Tile());
}
}
...
vec2 index_to_coords(unsigned index)
{
return vec2(index % board_width, index / board_width);
}
...
unsigned coords_to_index(const vec2& coords)
{
return (static_cast<unsigned>(coords.y) * board_width) + static_cast<unsigned>(coords.x);
}
我同意 Fibbles 的观点,但我想提供一个替代想法。 Fibble 的方法实际上甚至在 C 语言中也很常见,因为多维结构(矩阵)那样更容易。
但是,如果你坚持二维概念,你可以嵌套向量。考虑:
typedef std::vector< tile > TileRow;
typedef std::vector< TileRow > Tiles;
起初,这可能有点令人困惑,所以要明确创建:
std::vector< std::vector< tile > > t;
然而,对于 typedef,那就是
Tiles t;
现在,那是空的。要使用它,您需要推入一些行,并为每一行推入一些列。你可能不喜欢那样,所以......你可以使用分配功能来设置一些行。例如,如果您需要一个 10 行乘 10 列的矩阵,您可能
t.assign( 10, TileRow( 10, tile() ) );
这里假设 tile 有一个默认构造函数,推送 10 行 TileRow,每行有 10 列默认构造的 tiles。
现在,t[ 1 ]
returns 对第 1 行的引用。因此,t[ 1 ][ 1 ]
是对位置 1,1 处的图块的引用,很像数组。
但是,现在您没有 allocation/deallocation 问题。
类似的事情可以用 std::array 完成,甚至更好。
typedef std::array< tile, 10 > TileRow;
typedef std::array< TileRow, 10 > Tiles;
Tiles t;
此时,t 已准备好使用默认的初始化图块。