对象如何将自身添加到对象类中的向量中?

How would a object add itself to a vector inside the object's class?

本文关键字:对象 向量 添加      更新时间:2023-10-16

我对类很陌生。

粒子如何将自己添加到类中的 std::vector 中?

我的代码:

std::vector<Particle> particles;
class Particle
{
public:
Particle(sf::Vector2f position)
{
particles.push_back(/*add this Particle into vector particles*/);
}
};
std::vector<Particle>

存储粒子,因此它无法将"自身"添加到该向量中,它可以添加副本,但这可能不是您想要的。

emplace_back可用于将粒子构造到向量本身中:

particles.emplace_back(position); // Will call Particle(position)

如果您确实想要副本,只需尊重this指针,但这可能会令人困惑。不要在复制/移动构造函数或复制/移动赋值运算符中执行此操作,因为它们可以在插入/删除/等过程中由向量本身调用。

Particle(sf::Vector2f position)
{
particles.push_back(*this);
}

否则,您可以将指针存储在向量中。这带来了额外的问题,比如谁负责释放它们,而粒子系统之类的东西可能会对性能产生重大影响。

std::vector<Particle*> particles;
class Particle
{
public:
Particle(sf::Vector2f position)
{
particles.push_back(this); // Dangerous
// If an exception happens after push_back this object will be destroyed,
// but particles will still contain that now invalid pointer.
}
};

...
auto particle = new Particle(position); // Who deletes this?

如果粒子负责删除,则可以使用std::unique_ptr,但在构造函数中这样做可能不安全。

std::vector<std::unique_ptr<Particle>> particles;
class Particle
{
public:
Particle(sf::Vector2f position)
{
particles.push_back(std::unique_ptr<Particle>(this)); // Dangerous
// If an exception happens in push_back or after this in the constructor
// the exception will cause this Particle to be destroyed, but this unique_ptr
// will be left with an invalid pointer, and try and delete it as well.
}
};

...
new Particle(position);

最好在外面做,在其他一些功能中。

std::vector<std::unique_ptr<Particle>> particles;
class Particle
{
public:
Particle(sf::Vector2f position)
{}
};
...
particles.push_back(std::make_unique<Particle>(position));

如果你只需要将粒子的副本推送到向量,那么你可以取消引用this指针并将其推送到向量中,如下所示:

particles.push_back(*this)

不过,这将创建一个副本,并且不引用调用它的原始对象,而是一个全新的对象。如果要将原始粒子推送到矢量,则需要使矢量存储为Particle*。然后,您可以将当前粒子推送到矢量,如下所示:

std::vector<Particle*> particles;
class Particle
{
public:
Particle(/* Your constructor args */)
{
particles.push_back(this)
}
}

我建议你放弃到目前为止的所有答案;并创建一个新的包装类;因为我认为从根本上说,你的设计很弱。

class Particle {};
struct ParticleGroup {
Particle& createParticle() {
particles.push_back(Particle());
return particles.back();
}
std::vector<Particle> particles;
};

这样做的乐趣在于,你现在可以创建一个粒子,它不会被强行撞击到你的矢量中(这可能对测试/序列化/其他用途有用(;但你已经做到了,如果你去你的粒子组;你不必担心粒子是如何存储的。 (例如,当你意识到你实际上想要一个列表,因为随机删除;你不想重写所有内容!(