C++ 对某些阶级成员的适当破坏

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

我有一个类,它有几个指针成员,可以重新分配。当我使用LoadOBJ()函数时,我应该替换已经保存的数据,但是我在垃圾收集方面遇到了问题。下面是一些代码

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应该为客户端提供一些服务,并保持其内部私有