不同的析构函数类型



我有一个名为Chunk的对象,它包含一个指向b2Body的指针。它做其他重要的事情,但为了简单起见,我去掉了这些。小心,聪明的指针不起作用(我想),你会明白为什么的。

class DChunk
{
public:
DChunk();
DChunk(const DChunk& old);
virtual ~DChunk();
virtual b2Body* getBody() const;
private:
b2Body* m_pBody;//pointer;
};

问题是,如何定义何时删除m_pBody对象。

如果我想复制这个对象,比如说有一个这些东西的向量,我推送另一个,它会调用copy Constructor,复制m_pBody的内存地址(这就是我想要的),然后删除旧的。如果这个对象上的Destructor删除了m_pBody,那显然很糟糕,因为新副本没有有效的内存地址,但如果它不删除它,那么m_pBody将永远不会被删除,并且当没有更多的Chunk指向它时,它需要被删除。

删除m_pBody对象的唯一正确方法是调用m_pBody->GetWorld()->DestroyBody(m_pBody);这不在我的控制之下,所以聪明的指针真的不起作用。我希望有不同类型的析构函数可以被适当地调用,比如在向量中进行复制。此外,如果有帮助的话,不应该有一个以上的区块与一个b2Body关联。

我假设你有类似的东西

vector<DChunck> myvec;

你担心做

obj=DChunk()
myvec.push_back(obj)

首先(这是一种非常适合初学者的方法,避免使用智能指针或任何C++11)创建容器DChunk对象有一些不太正确的地方。这是因为当你申报时

vector<DChunk>

你告诉你的向量,它将接收DChunk大小的对象。但是,由于该类包含一个指向数组的指针m_pBody(数组的大小不会是恒定的!),因此这种方法对C++来说不会太"健康"。考虑到这一点,您可以做其他事情,坚持您的类设计:创建一个指针容器!您可以创建

vector<DChunk*> myvec;

如果你想把一个物体添加到向量中,你只需要做

DChunk *obj = new DChunk();
myvec.push_back(event);

因为现在容器正在处理指针,可以在不干扰对象内容的情况下处理指针,从而避免了对析构函数的担忧。调用对象的方法现在将是,例如,

(*myvec[3]).getBody()

或(清洁版)

myvec[3]->getBody()

希望我解决了你的问题

您还可以提供move构造函数,这样它就可以移动东西,而不是复制。。。这是我几个小时前做的一个例子,因为我有同样的问题(我不知道这些构造函数的顺序是什么,什么时候被调用,"&&"也是移动构造函数):

移动构造函数类似于复制构造函数。不同的是,在move构造函数中,不是复制值和内容,而是将给定对象的指针(而不是复制)和值分配给一个新对象(this->temp=OldClass.temp),然后使OldClass.ttemp=NULL;这样,当不可避免的析构函数被调用时,它会找到一个NULL指针,而不会删除它。

#include <iostream>
#include <Windows.h>
class MyClass
{
public:
MyClass()
{
temp = new RECT();
ZeroMemory(temp, sizeof(RECT));
}
MyClass(int x, int y)
{
temp = new RECT();
ZeroMemory(temp, sizeof(RECT));
temp->left = x;
temp->top = y;
}
MyClass(MyClass &&OldClass)
{
if (this->temp != NULL)
{
delete this->temp;
this->temp = NULL;
}
temp = OldClass.temp;
OldClass.temp = NULL;
}
MyClass& operator=(MyClass &&OldClass)
{
if (this->temp != NULL)
{
delete this->temp;
this->temp = NULL;
}
temp = OldClass.temp;
OldClass.temp = NULL;
return *this;
}
MyClass(const MyClass &OldClass)
{
*temp = *OldClass.temp;
}
MyClass& operator=(const MyClass &OldClass)
{
*temp = *OldClass.temp;
return *this;
}
~MyClass()
{
if (this->temp != NULL)
{
delete this->temp;
this->temp = NULL;
}
}
void Print()
{
std::cout << temp << " " << temp->left << " " << temp->top << " " << temp->right << " " << temp->bottom << 'n';
}
private:
RECT *temp;
};
int main()
{
MyClass bla, cha(54, 48);
bla.Print();
cha.Print();
bla = MyClass(2, 2);
bla.Print();
bla = cha;
bla.Print();
cha = MyClass(54, 2);
cha.Print();
std::cin.get();
return 0;
}

通常,正确的内存管理是一项不平凡的任务,并且不存在通用决策。一些简单而常见的已知方法在最新的库中以"智能指针"类型的形式出现(您也可以自己定义它们(通过复制已知的"标准定义")。但它也不是一个完全普遍的:-)你的问题似乎是一个普遍解决方案的问题。其他一些编程语言(java…,而不是C++)宣传你要解决这个问题(通过语言实现的内置方法)。你写道:"此外,如果有帮助的话,一个b2Body永远不应该有一个以上的Chunk。"然后问题似乎消失了(因为Chunk根本无法复制)。(?)

最新更新