我需要创建几个对象并将它们放入一个列表中(我正在使用 std::vector )。另外,我需要列表项指向对象的地址,以便我对对象所做的更改也反射(reflect)在列表中。 但问题是,列表中的每个项目都指向循环中创建的最后一个对象。
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
Grass g1;
g1.position.x = i;
g1.position.y = j;
grassList.push_back(&g1);
}
}
列表中草对象的属性应该是..
[0,0]
[0,1]
[0,2]
.
.
.
.
[49,49]
但是结果是..
[49,49]
[49,49]
[49,49]
[49,49]
.
.
.
[49,49]
最佳答案
(现代 C++ 更新在最后)
如果您习惯使用变量引用计数的其他语言,您可能会想到这一点
Grass g1;
在循环的每次迭代中创建一个新的“Grass”对象。事实并非如此,C++ 不是一种引用计数语言。
相反,它在堆栈上创建一个作用域局部变量。
因为您在循环中执行此操作,所以它可能每次都位于内存中的同一位置。
您需要:
不用指针,只需让容器成为 Grass 对象的容器:让容器为您处理分配。
使用 C++11 的
unique_ptr
和 C++14 的make_unique
为循环的每次迭代动态创建 Grass 实例。当包含 unique_ptr 的 vector 超出范围时,它们将被自动释放。使用
new
和delete
关键字手动分配和释放指向的Grass对象。
选项 1:
#include <vector>
struct Grass {
struct {
int x, y;
} position;
};
int main() {
std::vector<Grass> grassList;
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
Grass g1;
g1.position.x = i;
g1.position.y = j;
grassList.push_back(g1);
}
}
}
选项 2:
#include <memory>
#include <vector>
struct Grass {
struct {
int x, y;
} position;
};
int main() {
std::vector<std::unique_ptr<Grass>> grassList;
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
auto g1 = std::make_unique<Grass>();
g1->position.x = i;
g1->position.y = j;
grassList.push_back(std::move(g1));
}
}
}
选项 3:
#include <vector>
struct Grass {
struct {
int x, y;
} position;
};
int main() {
std::vector<Grass*> grassList;
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
Grass* g1 = new Grass;
g1->position.x = i;
g1->position.y = j;
grassList.push_back(g1);
}
}
// ...
for (auto& g1: grassList) {
delete g1;
}
grassList.clear();
}
<小时/>
C++11 引入了 emplace_back
,它允许您一次性分配和构造容器中的条目。
#include <vector>
struct Grass {
struct {
int x, y;
} position;
// because x and y are inside a private sub-struct,
// we'll need a constructor to pass the values in.
Grass(int x, int y) : position{x, y} {}
};
int main() {
std::vector<Grass> grassList{}; // default initialized.
static constexpr size_t dim = 10; // name the constant (DIMension)
grassList.reserve(dim); // allocate memory in advance
for (auto i = 0; i < dim; i++) {
for(auto j = 0; j < dim; j++) {
grassList.emplace_back(i, j);
}
}
// no cleanup required
}
关于c++ - 将对象的地址添加到循环 vector 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36731985/