C++ 将对象添加到for循环中的向量

C++ 将对象添加到for循环中的向量,c++,vector,directx,C++,Vector,Directx,我正在尝试向同一类型的向量添加一些对象。 在标题中: std::vector<Object_3D> balls_; 我在第三次运行for循环时出错,因为调用了object_3d析构函数。但我不知道为什么。析构函数是调用Model::Release()的地方,我认为它位于调用堆栈的顶部。这是调用堆栈: s3d_app.exe!abfw::Model::Release() Line 26 C++ s3d_app.exe!Object_3D::~Object_3D() Line 9

我正在尝试向同一类型的向量添加一些对象。 在标题中:

std::vector<Object_3D> balls_;
我在第三次运行for循环时出错,因为调用了object_3d析构函数。但我不知道为什么。析构函数是调用Model::Release()的地方,我认为它位于调用堆栈的顶部。这是调用堆栈:

s3d_app.exe!abfw::Model::Release() Line 26  C++
s3d_app.exe!Object_3D::~Object_3D() Line 9  C++
s3d_app.exe!Object_3D::`scalar deleting destructor'(unsigned int)   C++
s3d_app.exe!std::allocator<Object_3D>::destroy<Object_3D>(Object_3D * _Ptr) Line 624    C++
s3d_app.exe!std::allocator_traits<std::allocator<Object_3D> >::destroy<Object_3D>(std::allocator<Object_3D> & _Al, Object_3D * _Ptr) Line 758   C++
s3d_app.exe!std::_Wrap_alloc<std::allocator<Object_3D> >::destroy<Object_3D>(Object_3D * _Ptr) Line 909 C++
s3d_app.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<Object_3D> > >(Object_3D * _First, Object_3D * _Last, std::_Wrap_alloc<std::allocator<Object_3D> > & _Al, std::_Nonscalar_ptr_iterator_tag __formal) Line 89    C++
s3d_app.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<Object_3D> > >(Object_3D * _First, Object_3D * _Last, std::_Wrap_alloc<std::allocator<Object_3D> > & _Al) Line 80   C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::_Destroy(Object_3D * _First, Object_3D * _Last) Line 1480    C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::_Reallocate(unsigned int _Count) Line 1515   C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::_Reserve(unsigned int _Count) Line 1532  C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::push_back(const Object_3D & _Val) Line 1199  C++

怎么了

  • 您没有成员的值初始化。当构造函数(无论是复制构造函数、默认构造函数、特殊构造函数等)完成时所有成员变量都应该在某种意义上进行初始化

  • 你公然违反了法律。您需要遵守它,因为您有一个资源释放析构函数,因此需要一个资源复制(或至少是资源共享)复制构造函数和赋值操作符

代码崩溃的原因

您的
Object\u3d
类包含动态资源(模型就是这样的资源之一)。当您将新初始化的对象推送到向量中时,会生成对象的浅层副本,因为您没有提供自定义的复制/赋值语义。因此,将调用为类提供的隐式复制构造函数。这意味着推送完成后,您现在有两个对象,它们包含对相同数据的动态资源引用。当循环体循环后循环中的本地对象被销毁时,析构函数将释放这些资源,向量中的副本将保留无效的资源引用。稍后访问这些引用会触发崩溃

如何修复它

使用该方法实现对象,或使用唯一对象实现单一所有权共享资源。后者可以使用智能指针和向量来完成。我不熟悉您正在使用的工具包,因此提供硬代码解决方案是不可能的,但可以说,您的对象必须完全拥有自己的资源(因此必须对适当的复制/分配语义进行编码),或者必须开发一种共享机制,允许多个对象共享对同一资源的引用,最后一个出门的人会关灯


如何实现这一点,我留给你,但至少你知道你的问题。

听起来你的问题可能来自于向量增长时自身的大小调整。当向量调整大小时,它会分配新内存,将其所有元素复制到新内存,然后销毁旧元素。你有适合你的对象的复制构造函数吗?复制新对象然后销毁旧对象是否有问题?在将对象放入标准容器之前,这些问题都需要很好的回答。在您的
InitGameObjects
循环中,您创建一个
对象\u 3D
,然后将其添加到向量中,而不是更改同一对象,然后(一次又一次)添加。您需要在每次迭代中创建一个新的(可能是使用
std::make_shared
,然后将生成的
shared_ptr
添加到向量中。那么..立即
Object_3D
是否完全兼容?将我的注释添加到@YoungJohn中,一个对象可能会一次又一次地被破坏。@Steve我希望副本被推回,而不是同一个对象。
void Object_3D::Init(abfw::Platform& platform_, const char *filename){
    abfw::OBJLoader obj_loader;
    obj_loader.Load(filename, platform_, model_);
    mesh_instance_.set_mesh(model_.mesh());
    transform_.SetIdentity();
    mesh_instance_.set_transform(transform_);
    position_ = transform_.GetTranslation();
}
s3d_app.exe!abfw::Model::Release() Line 26  C++
s3d_app.exe!Object_3D::~Object_3D() Line 9  C++
s3d_app.exe!Object_3D::`scalar deleting destructor'(unsigned int)   C++
s3d_app.exe!std::allocator<Object_3D>::destroy<Object_3D>(Object_3D * _Ptr) Line 624    C++
s3d_app.exe!std::allocator_traits<std::allocator<Object_3D> >::destroy<Object_3D>(std::allocator<Object_3D> & _Al, Object_3D * _Ptr) Line 758   C++
s3d_app.exe!std::_Wrap_alloc<std::allocator<Object_3D> >::destroy<Object_3D>(Object_3D * _Ptr) Line 909 C++
s3d_app.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<Object_3D> > >(Object_3D * _First, Object_3D * _Last, std::_Wrap_alloc<std::allocator<Object_3D> > & _Al, std::_Nonscalar_ptr_iterator_tag __formal) Line 89    C++
s3d_app.exe!std::_Destroy_range<std::_Wrap_alloc<std::allocator<Object_3D> > >(Object_3D * _First, Object_3D * _Last, std::_Wrap_alloc<std::allocator<Object_3D> > & _Al) Line 80   C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::_Destroy(Object_3D * _First, Object_3D * _Last) Line 1480    C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::_Reallocate(unsigned int _Count) Line 1515   C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::_Reserve(unsigned int _Count) Line 1532  C++
s3d_app.exe!std::vector<Object_3D,std::allocator<Object_3D> >::push_back(const Object_3D & _Val) Line 1199  C++
#include <graphics/mesh_instance.h>
#include <graphics/model.h>
#include <assets/png_loader.h>
#include <assets/obj_loader.h>
#include <maths/vector3.h>


class Object_3D{
public:
    Object_3D();
    ~Object_3D();

    void Init(abfw::Platform& platform, const char*);
    void SetTranslation(abfw::Vector3 transform_);
    void SetScale(abfw::Vector3 scale_);
    void Move(abfw::Vector3 move_);
    abfw::Model& GetModel();
    abfw::MeshInstance GetMeshInstance();
    abfw::Matrix44 GetTransform();

    abfw::Vector3 position_;
private:
    abfw::Model model_;
    abfw::MeshInstance mesh_instance_;
    abfw::Matrix44 transform_;
};
#include "Object_3D.h"

Object_3D::Object_3D(){

}

Object_3D::~Object_3D(){
    model_.Release();
}

void Object_3D::Init(abfw::Platform& platform_, const char *filename){
    abfw::OBJLoader obj_loader;
    obj_loader.Load(filename, platform_, model_);
    mesh_instance_.set_mesh(model_.mesh());
    transform_.SetIdentity();
    mesh_instance_.set_transform(transform_);
    position_ = transform_.GetTranslation();
}

abfw::Model& Object_3D::GetModel(){
    return model_;
}

abfw::MeshInstance Object_3D::GetMeshInstance(){
    return mesh_instance_;
}

void Object_3D::SetTranslation(abfw::Vector3 position_vector_){
    position_ = position_vector_;
    transform_.SetTranslation(position_);
    mesh_instance_.set_transform(transform_);
}

void Object_3D::Move(abfw::Vector3 move_){

    position_ += move_;
    transform_.SetTranslation(position_);
    mesh_instance_.set_transform(transform_);
}

void Object_3D::SetScale(abfw::Vector3 scalingVector){
    transform_.Scale(scalingVector);
    mesh_instance_.set_transform(transform_);
}

abfw::Matrix44 Object_3D::GetTransform(){
    return transform_;
}