C++析构函数(带有代码示例)
C++ Destructor (With Code Example)
我刚刚从Java切换到C++,到目前为止一切都很顺利。语言有点难,但我觉得我正在赶上。不过,我有一个关于析构函数的问题,为此我将提供我当前的代码,希望有人可以澄清我应该做什么以及如何进行。
我正在用OpenGL编写一个游戏,并创建了三个类:Vector3D,Dimension3D和Cuboid。我的问题从这个开始,我的长方体有一个 Vector3D 和 Dimension3D 的实例,你很快就会看到。我需要知道我的 Cuboid 类被标记为删除后会发生什么(确切的例程)。或者更准确地说,如果我需要在发生此类事件时显式销毁 Vector3D 和 Dimension3D 实例。我希望我充分阐述了这个问题。
这是我的课程。
(矢量3D.cpp)
#include "Vector3D.h"
Vector3D::Vector3D(){
}
Vector3D::Vector3D( const float& x , const float& y , const float& z ){
this->x = x;
this->y = y;
this->z = z;
}
Vector3D::~Vector3D(){
}
void Vector3D::setX( const float& x ){
this->x = x;
}
void Vector3D::setY( const float& y ){
this->y = y;
}
void Vector3D::setZ( const float& z ){
this->z = z;
}
float Vector3D::getX(){
return x;
}
float Vector3D::getY(){
return y;
}
float Vector3D::getZ(){
return z;
}
(矢量3D.h)
#ifndef NE3_Vector3D_H_
#define NE3_Vector3D_H_
class Vector3D{
public:
Vector3D();
Vector3D( const float& , const float& , const float& );
~Vector3D();
void setX( const float& );
void setY( const float& );
void setZ( const float& );
void setPosition( const float& , const float& , const float& );
float getX();
float getY();
float getZ();
float x;
float y;
float z;
private:
// Private Members Go Here
};
#endif // NE3_Vector3D_H_
(维度3D.cpp)
#include "Dimension3D.h"
Dimension3D::Dimension3D(){
}
Dimension3D::Dimension3D( const float& width , const float& height , const float& depth ){
this->width = width;
this->height = height;
this->depth = depth;
}
Dimension3D::~Dimension3D(){
}
void Dimension3D::setWidth( const float& width ){
this->width = width;
}
void Dimension3D::setHeight( const float& height ){
this->height = height;
}
void Dimension3D::setDepth( const float& depth ){
this->depth = depth;
}
float Dimension3D::getWidth(){
return width;
}
float Dimension3D::getHeight(){
return height;
}
float Dimension3D::getDepth(){
return depth;
}
(维度3D.h)
#ifndef NE3_Dimension3D_H_
#define NE3_Dimension3D_H_
class Dimension3D{
public:
Dimension3D();
Dimension3D( const float& , const float& , const float& );
~Dimension3D();
void setWidth( const float& );
void setHeight( const float& );
void setDepth( const float& );
void setSize( const float& , const float& , const float& );
float getWidth();
float getHeight();
float getDepth();
float width;
float height;
float depth;
private:
// Private Members Go Here
};
#endif // NE3_Dimension3D_H_
最后,我正在进行的工作Cuboid.cpp和Cuboid.h
(长方体.cpp)
#include "Cuboid.h"
Cuboid::Cuboid(){
}
Cuboid::Cuboid(const Vector3D& location, const Dimension3D& dimension){
this->location = location;
this->dimension = dimension;
}
Cuboid::~Cuboid(){
// Do i do delete both location and dimension here?
}
void Cuboid::drawImmediate(){
}
void Cuboid::drawVBO(){
}
(长方体)
#ifndef NE3_CUBOID_H_
#define NE3_CUBOID_H_
#include "Vector3D.h"
#include "Dimension3D.h"
class Cuboid{
public:
Cuboid();
Cuboid( const Vector3D& , const Dimension3D& );
~Cuboid();
void drawImmediate();
void drawVBO();
Vector3D location;
Dimension3D dimension;
private:
};
#endif // NE3_CUBOID_H_
我在析构函数中.cpp在 Cuboid 中留下了评论。我想知道我是否应该删除那里的Vector3D和Dimension3D,以及一个显示最佳方法的示例。IE:表示此功能的任何常见约定。
如果我的问题不够充分,我将非常乐意提供进一步的澄清。另外,我确信还有其他类似的问题,但是,我需要在自己的代码中看到它才能完全掌握它。(奇怪的学习方式),所以如果这变成重复,请原谅我。
在这种特殊情况下,您不需要任何显式销毁代码。
这样做的原因是您使用的是直接成员:
class Cuboid {
public:
Vector3D location;
};
这意味着Vector3D
对象嵌入到Cuboid
的内存中,并与Cuboid
一起自动分配和释放。
如果您有一个指向对象的指针作为成员,情况会有所不同(例如Vector3D *location
) 而不是成员本身。在这种情况下,您还必须为location
显式分配内存,并在析构函数中显式释放它。
由于您刚刚开始使用C++,因此您可以使用的初学者经验法则是仅显式删除显式分配的内容。
由于您没有自己分配Vector3D
(例如通过new
),因此不应将其删除。
如果你的代码看起来像这样,情况会有所不同,
// Cuboid.cpp
Cuboid::Cuboid(){
location = new Vector3d;
}
Cuboid::~Cuboid(){
delete location; // now this is necessary
}
// Cuboid.hpp
class Cuboid {
private:
Vector3D* location; // using a raw pointer here, this can be different for scoped/RAII pointer, unique_ptr
};
另外,考虑将成员设为私有,封装在C++中和在 Java 中一样重要。
然后,随着C++的进行,您会遇到 RAII,这是一个稍微高级的主题,它使上述经验法则无效,因为您将使用语言结构或您自己的作用域/RAII 类以确定性的方式为您处理释放。例如,在以下情况下,
std::unique_ptr<Vector3D> location(new Vector3D);
您不需要自己解除分配location
,当unique_pointer超出当前作用域块时,或者当封闭对象(location
是其成员)将被解除分配时,C++ 标准库将自动解除分配。
如果你在类Cuboid
的构造函数中动态分配了Vector3D
对象和Dimension3D
对象,那么你需要在类Cuboid
的析构函数中删除它们:
Cuboid::Cuboid(const Vector3D& location, const Dimension3D& dimension){
this->location = new Vector3D(location);
this->dimension = new Dimension3D(dimension);
}
Cuboid::~Cuboid(){
delete location;
delete dimension;
}
但由于代码中不是这种情况,因此不需要删除这些对象。
无论你是用Cuboid* x = new Cuboid(...)
动态分配一个Cuboid
对象,还是用Cuboid x(...)
静态分配一个对象,一旦调用类Cuboid
的(空)析构函数,这两个成员对象(location
和dimension
)就会被隐式销毁。
不需要在其构造函数中删除长方体的位置和维度成员。当 Cuboid 实例被销毁时,会自动调用它们的析构函数,因为您没有显式管理它们的内存分配,即您在创建它们时没有使用">new"。
此外,根据您展示的代码,Vector3D 和 Dimension3D 类也不需要在其析构函数中进行任何手动资源管理。基本上,如果您不使用new为任何对象分配内存,则通常无需担心释放它们。
不,您不需要location
和dimension
解除分配成员,因为它们是自动对象的自动对象,其生存期是自动控制的。当类Cuboid
被销毁时,它们将自动销毁。
事实上,对指向本地自动对象的指针执行delete
是未定义的行为。
作为最佳实践,您不应该在C++中使用delete
(除非您知道自己在做什么)。如果您需要动态分配内存(并且标准库中的容器不执行这项工作),那么您应该使用智能指针,如std::shared_ptr
,它可以为您处理释放(请参阅 RAII)。
- 如何析构单例实例,或者为什么以下代码适用于析构函数?
- 添加虚拟析构函数会使代码大小膨胀
- 如何在析构函数中执行一些代码*在*成员被销毁之后
- 旧代码在析构函数中引发异常
- 我应该如何在此代码中编写析构函数
- C++析构函数(带有代码示例)
- 从本地类的 C++ 析构函数访问返回代码
- 为什么代码调用析构函数两次
- 复制构造函数、赋值运算符和析构函数代码重复
- 我无法让我的析构函数在我的代码中工作
- 为什么在以下代码中调用析构函数
- 析构函数在这段代码中隐藏在哪里
- 清理C++异常析构函数中的代码
- 为什么构造函数/析构函数在g++生成的程序集代码中是这样定义的
- 使用析构函数后,代码显示"reference to Book::~Book()"错误
- 使用指针和析构函数的c++代码设计
- [C++]在此代码之前不存在的析构函数中引发的内存错误。尝试创建一个新的动态数组并填充它
- 如何编写析构函数才能编译代码并释放所有分配的内存
- 代码可以工作,但在析构函数中崩溃(没有复制构造函数)
- 如果声明析构函数,为什么此代码无法编译?