C++ 对某些阶级成员的适当破坏
我有一个类,它有几个指针成员,可以重新分配。当我使用LoadOBJ()函数时,我应该替换已经保存的数据,但是我在垃圾收集方面遇到了问题。下面是一些代码C++ 对某些阶级成员的适当破坏,c++,memory-leaks,garbage-collection,C++,Memory Leaks,Garbage Collection,我有一个类,它有几个指针成员,可以重新分配。当我使用LoadOBJ()函数时,我应该替换已经保存的数据,但是我在垃圾收集方面遇到了问题。下面是一些代码 class Object3d{ public: int nVertex; int nFace; int nVertexNormal; Vector3d *vertex; Vector3d *vertexNormal; Face3d *face; void LoadOBJ(char*); Object3d():nVertex(0), nFa
class Object3d{
public:
int nVertex;
int nFace;
int nVertexNormal;
Vector3d *vertex;
Vector3d *vertexNormal;
Face3d *face;
void LoadOBJ(char*);
Object3d():nVertex(0), nFace(0), vertex(NULL), face(NULL){}
Object3d(char*);
~Object3d(){}
};
Face3d:
struct Face3d{
int nFaceV;
int *iVertex;
int *iVertexNormal;
Face3d():nFaceV(0){}
};
每次使用LoadOBJ()函数加载新对象时,我都希望删除以前分配的内存,而不仅仅是使用new
和泄漏以前分配的内存
我不知道该怎么做。这就是我现在的想法:
void *vGarbage, *vGarbage2,
*fGarbage,
*iGarbage, *iGarbage2;
//nFace is the previous number of faces; in the case of a new object, it's 0
for(int i=0; i<nFace; i++)
{
iGarbage=face[i].iVertex;
iGarbage2=face[i].iVertexNormal;
delete[] iGarbage;
delete[] iGarbage2;
}
vGarbage=vertex;
fGarbage=face;
vGarbage2=vertexNormal;
delete[] vGarbage;
delete[] vGarbage2;
delete[] fGarbage;
void*vGarbage,*vGarbage2,
*fGarbage,
*iGarbage,*iGarbage2;
//nFace是以前的面数;对于新对象,它是0
对于(inti=0;i检查C++11),它们提供了分配内存的能力,当对象超出范围时,将自动释放内存
#include <memory>
#include <iostream>
struct Foo {
Foo() { std::cout << "Foo...\n"; }
~Foo() { std::cout << "~Foo...\n"; }
};
struct D {
void operator()(Foo* p) const {
std::cout << "Call delete for Foo object...\n";
delete p;
}
};
int main()
{
{
std::cout << "constructor with no managed object\n";
std::shared_ptr<Foo> sh1;
}
{
std::cout << "constructor with object\n";
std::shared_ptr<Foo> sh2(new Foo);
std::shared_ptr<Foo> sh3(sh2);
std::cout << sh2.use_count() << '\n';
std::cout << sh3.use_count() << '\n';
}
{
std::cout << "constructor with object and deleter\n";
std::shared_ptr<Foo> sh4(new Foo, D());
}
}
#包括
#包括
结构Foo{
Foo(){std::cout检查一下C++11,它们提供了分配内存的能力,当对象超出范围时,内存将自动释放
#include <memory>
#include <iostream>
struct Foo {
Foo() { std::cout << "Foo...\n"; }
~Foo() { std::cout << "~Foo...\n"; }
};
struct D {
void operator()(Foo* p) const {
std::cout << "Call delete for Foo object...\n";
delete p;
}
};
int main()
{
{
std::cout << "constructor with no managed object\n";
std::shared_ptr<Foo> sh1;
}
{
std::cout << "constructor with object\n";
std::shared_ptr<Foo> sh2(new Foo);
std::shared_ptr<Foo> sh3(sh2);
std::cout << sh2.use_count() << '\n';
std::cout << sh3.use_count() << '\n';
}
{
std::cout << "constructor with object and deleter\n";
std::shared_ptr<Foo> sh4(new Foo, D());
}
}
#包括
#包括
结构Foo{
Foo(){std::cout可能会回答您的问题。我认为您必须将void指针强制转换为特定的指针,如int*,才能使其正常工作。但其行为高度依赖于您使用的编译器
编辑:使用智能指针的建议可能是解决您的问题的最简单和最安全的方法。可能会回答您的问题。我认为您必须将void指针强制转换为特定的指针,如int*,以使其工作。但行为高度依赖于您使用的编译器
编辑:使用智能指针的建议可能是解决问题的最简单、最安全的方法。我知道您希望在重新签名这些成员之前释放Object3d::vertex
、Object3d::vertexNormal
和Object3d::face
占用的内存。首先,您应该为这些成员提供自定义析构函数您的Face3d
,这样您就不再需要关心它在包含类中的成员。即:
face3d::~face3d() {
if (iVertex) delete[] iVertex;
if (iVertexNormal) delete[] iVertexNormal;
}
在Object3d
类中,可以使用专用的清理功能:
void Object3d::cleanup() {
if (face) delete[] face;
face = nullptr;
if (vertex) delete[] vertex;
vertex = nullptr;
if (vertexNormal) delete[] vertexNormal;
vertexNormal = nullptr;
nVertex = 0;
nFace = 0;
nVertexNormal = 0;
}
顺便说一句,在析构函数Object3d::~Object3d()中
您也必须调用该函数。我知道您想释放Object3d::vertex
、Object3d::vertexNormal
和Object3d::face
所占用的内存,然后再重新签名这些成员。首先,您应该为Face3d
提供自定义析构函数,这样您就不再需要关心它是包含类中的成员。即:
face3d::~face3d() {
if (iVertex) delete[] iVertex;
if (iVertexNormal) delete[] iVertexNormal;
}
在Object3d
类中,可以使用专用的清理功能:
void Object3d::cleanup() {
if (face) delete[] face;
face = nullptr;
if (vertex) delete[] vertex;
vertex = nullptr;
if (vertexNormal) delete[] vertexNormal;
vertexNormal = nullptr;
nVertex = 0;
nFace = 0;
nVertexNormal = 0;
}
顺便说一句,在析构函数中,也必须调用该函数。使用std::vector而不是手动管理的数组:
struct Face3d{
int nFaceV;
std::vector<int> iVertex;
std::vector<int> iVertexNormal;
Face3d():nFaceV(0){}
};
class Object3d{
public:
std::vector<Vector3d> vertex;
std::vector<Vector3d> vertexNormal;
std::vector<Face3d> face;
void LoadOBJ(char*);
Object3d():nVertex(0), nFace(0), vertex(NULL), face(NULL){}
Object3d(char*);
~Object3d(){}
};
struct Face3d{
国际nFaceV;
std::vector-iVertex;
std::向量正常;
Face3d():nFaceV(0){}
};
类Object3d{
公众:
向量顶点;
std::向量顶点法线;
向量面;
void LoadOBJ(char*);
Object3d():nVertex(0),nFace(0),顶点(NULL),面(NULL){}
Object3d(char*);
~Object3d(){}
};
<>这将免除编写析构函数的负担。正如上面已经说过的,这是例证C++中的RAII模式,它应该被用来代替人工资源管理。
一般来说,公共数据成员几乎总是一个坏主意,因为它破坏了封装。Object3d应该为客户端提供一些服务,并保持其内部私有。使用std::vector而不是手动管理的数组:
struct Face3d{
int nFaceV;
std::vector<int> iVertex;
std::vector<int> iVertexNormal;
Face3d():nFaceV(0){}
};
class Object3d{
public:
std::vector<Vector3d> vertex;
std::vector<Vector3d> vertexNormal;
std::vector<Face3d> face;
void LoadOBJ(char*);
Object3d():nVertex(0), nFace(0), vertex(NULL), face(NULL){}
Object3d(char*);
~Object3d(){}
};
struct Face3d{
国际nFaceV;
std::vector-iVertex;
std::向量正常;
Face3d():nFaceV(0){}
};
类Object3d{
公众:
向量顶点;
std::向量顶点法线;
向量面;
void LoadOBJ(char*);
Object3d():nVertex(0),nFace(0),顶点(NULL),面(NULL){}
Object3d(char*);
~Object3d(){}
};
<>这将免除编写析构函数的负担。正如上面已经说过的,这是例证C++中的RAII模式,它应该被用来代替人工资源管理。
一般来说,公共数据成员几乎总是一个坏主意,因为它破坏了封装。Object3d应该为客户端提供一些服务,并保持其内部私有